10
10
##
11
11
12
12
require 'msf/core'
13
- require 'rex '
13
+ require 'msf/core/post/common '
14
14
15
15
class Metasploit3 < Msf ::Post
16
16
17
+ include Msf ::Post ::Common
18
+
17
19
def initialize ( info = { } )
18
20
super ( update_info ( info ,
19
21
'Name' => "Windows Gather Directory Permissions Enumeration" ,
20
22
'Description' => %q{
21
23
This module enumerates directories and lists the permissions set
22
- on found directories.
24
+ on found directories. Please note: if the PATH option isn't specified,
25
+ then the module will start enumerate whatever is in the target machine's
26
+ %PATH% variable.
23
27
} ,
24
28
'License' => MSF_LICENSE ,
25
29
'Version' => '$Revision$' ,
26
30
'Platform' => [ 'win' ] ,
27
31
'SessionTypes' => [ 'meterpreter' ] ,
28
- 'Author' => [ 'Kx499' ]
32
+ 'Author' =>
33
+ [
34
+ 'Kx499' ,
35
+ 'Ben Campbell <eat_meatballs[at]hotmail.co.uk>' ,
36
+ 'sinn3r'
37
+ ]
29
38
) )
30
39
31
40
register_options (
32
41
[
33
- OptString . new ( 'PATH' , [ true , 'Directory to begin search from' , '' ] ) ,
42
+ OptString . new ( 'PATH' , [ false , 'Directory to begin search from' , '' ] ) ,
34
43
OptEnum . new ( 'FILTER' , [ false , 'Filter to limit results by' , 'NA' , [ 'NA' , 'R' , 'W' , 'RW' ] ] ) ,
35
44
OptInt . new ( 'DEPTH' , [ true , 'Depth to drill down into subdirs, O = no limit' , 0 ] ) ,
36
45
] , self . class )
@@ -59,8 +68,8 @@ def check_dir(dir, token)
59
68
# If path doesn't exist, do not continue
60
69
begin
61
70
session . fs . dir . entries ( dir )
62
- rescue
63
- print_error ( "Path seems invalid : #{ dir } ")
71
+ rescue => e
72
+ vprint_error ( " #{ e . message } : #{ dir } ")
64
73
return nil
65
74
end
66
75
@@ -90,41 +99,51 @@ def check_dir(dir, token)
90
99
if w [ "GrantedAccess" ] > 0 then result << "W" end
91
100
end
92
101
93
- def enum_subdirs ( dpath , maxdepth , token )
102
+ def enum_subdirs ( perm_filter , dpath , maxdepth , token )
94
103
filter = datastore [ 'FILTER' ]
95
104
filter = nil if datastore [ 'FILTER' ] == 'NA'
96
- dirs = session . fs . dir . foreach ( dpath )
105
+
106
+ begin
107
+ dirs = session . fs . dir . foreach ( dpath )
108
+ rescue Rex ::Post ::Meterpreter ::RequestError
109
+ # Sometimes we cannot see the dir
110
+ dirs = [ ]
111
+ end
112
+
97
113
if maxdepth >= 1 or maxdepth < 0
98
114
dirs . each do |d |
99
115
next if d =~ /^(\. |\. \. )$/
100
116
realpath = dpath + '\\' + d
101
117
if session . fs . file . stat ( realpath ) . directory?
102
118
perm = check_dir ( realpath , token )
103
- next if perm . nil?
104
- if !filter or perm . include? filter
119
+ if perm_filter and perm and perm . include? ( perm_filter )
105
120
print_status ( perm + "\t " + realpath )
106
121
end
107
- enum_subdirs ( realpath , maxdepth - 1 , token )
122
+ enum_subdirs ( perm_filter , realpath , maxdepth - 1 , token )
108
123
end
109
124
end
110
125
end
111
126
end
112
127
113
- def run
114
- t = 0 #holds impers token
128
+ def get_paths
129
+ p = datastore [ 'PATH' ]
130
+ return [ p ] if not p . nil? and not p . empty?
115
131
116
- #check and set vars
117
- if not datastore [ 'PATH' ] . empty?
118
- path = datastore [ 'PATH' ]
132
+ begin
133
+ p = cmd_exec ( "cmd.exe" , "/c echo %PATH%" )
134
+ rescue Rex ::Post ::Meterpreter ::RequestError => e
135
+ vprint_error ( e . message )
136
+ return [ ]
119
137
end
120
-
121
- depth = - 1
122
-
123
- if datastore [ 'DEPTH' ] > 0
124
- depth = datastore [ 'DEPTH' ]
138
+ print_status ( "Option 'PATH' isn't specified. Using system %PATH%" )
139
+ if p . include? ( ';' )
140
+ return p . split ( ';' )
141
+ else
142
+ return [ p ]
125
143
end
144
+ end
126
145
127
- #get impersonation token
146
+ def get_token
128
147
print_status ( "Getting impersonation token..." )
129
148
begin
130
149
t = get_imperstoken ( )
@@ -134,19 +153,51 @@ def run
134
153
vprint_error ( "Error #{ e . message } while using get_imperstoken()" )
135
154
vprint_error ( e . backtrace )
136
155
end
156
+ return t
157
+ end
137
158
138
- #loop through sub dirs if we have an impers token..else error
139
- if t == 0
140
- print_error ( "Getting impersonation token failed" )
141
- else
142
- print_status ( "Got token..." )
143
- print_status ( "Checking directory permissions from: " + path )
159
+ def enum_perms ( perm_filter , token , depth , paths )
160
+ paths . each do |path |
161
+ next if path . empty?
162
+ path = path . strip
163
+
164
+ print_status ( "Checking directory permissions from: #{ path } " )
165
+
166
+ perm = check_dir ( path , token )
167
+ if not perm . nil?
168
+ # Show the permission of the parent directory
169
+ if perm_filter and perm . include? ( perm_filter )
170
+ print_status ( perm + "\t " + path )
171
+ end
144
172
145
- is_path_valid = check_dir ( path , t )
146
- if not is_path_valid . nil?
147
173
#call recursive function to loop through and check all sub directories
148
- enum_subdirs ( path , depth , t )
174
+ enum_subdirs ( perm_filter , path , depth , token )
149
175
end
150
176
end
151
177
end
178
+
179
+ def run
180
+ perm_filter = datastore [ 'FILTER' ]
181
+ perm_filter = nil if datastore [ 'FILTER' ] == 'NA'
182
+
183
+ paths = get_paths
184
+ if paths . empty?
185
+ print_error ( "Unable to get the path" )
186
+ return
187
+ end
188
+
189
+ depth = -1
190
+ if datastore [ 'DEPTH' ] > 0
191
+ depth = datastore [ 'DEPTH' ]
192
+ end
193
+
194
+ t = get_token
195
+
196
+ if t == 0
197
+ print_error ( "Getting impersonation token failed" )
198
+ else
199
+ print_status ( "Got token: #{ t . to_s } ..." )
200
+ enum_perms ( perm_filter , t , depth , paths )
201
+ end
202
+ end
152
203
end
0 commit comments