Skip to content

Commit fc571b1

Browse files
author
jvazquez-r7
committed
Merge branch 'enum_dirperms_default_path' of https://github.com/wchen-r7/metasploit-framework into wchen-r7-enum_dirperms_default_path
2 parents bbb2f69 + e235aad commit fc571b1

File tree

1 file changed

+82
-31
lines changed

1 file changed

+82
-31
lines changed

modules/post/windows/gather/enum_dirperms.rb

Lines changed: 82 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -10,27 +10,36 @@
1010
##
1111

1212
require 'msf/core'
13-
require 'rex'
13+
require 'msf/core/post/common'
1414

1515
class Metasploit3 < Msf::Post
1616

17+
include Msf::Post::Common
18+
1719
def initialize(info={})
1820
super(update_info(info,
1921
'Name' => "Windows Gather Directory Permissions Enumeration",
2022
'Description' => %q{
2123
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.
2327
},
2428
'License' => MSF_LICENSE,
2529
'Version' => '$Revision$',
2630
'Platform' => ['win'],
2731
'SessionTypes' => ['meterpreter'],
28-
'Author' => ['Kx499']
32+
'Author' =>
33+
[
34+
'Kx499',
35+
'Ben Campbell <eat_meatballs[at]hotmail.co.uk>',
36+
'sinn3r'
37+
]
2938
))
3039

3140
register_options(
3241
[
33-
OptString.new('PATH', [ true, 'Directory to begin search from', '']),
42+
OptString.new('PATH', [ false, 'Directory to begin search from', '']),
3443
OptEnum.new('FILTER', [ false, 'Filter to limit results by', 'NA', [ 'NA', 'R', 'W', 'RW' ]]),
3544
OptInt.new('DEPTH', [ true, 'Depth to drill down into subdirs, O = no limit',0]),
3645
], self.class)
@@ -59,8 +68,8 @@ def check_dir(dir, token)
5968
# If path doesn't exist, do not continue
6069
begin
6170
session.fs.dir.entries(dir)
62-
rescue
63-
print_error("Path seems invalid: #{dir}")
71+
rescue => e
72+
vprint_error("#{e.message}: #{dir}")
6473
return nil
6574
end
6675

@@ -90,41 +99,51 @@ def check_dir(dir, token)
9099
if w["GrantedAccess"] > 0 then result << "W" end
91100
end
92101

93-
def enum_subdirs(dpath, maxdepth, token)
102+
def enum_subdirs(perm_filter, dpath, maxdepth, token)
94103
filter = datastore['FILTER']
95104
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+
97113
if maxdepth >= 1 or maxdepth < 0
98114
dirs.each do|d|
99115
next if d =~ /^(\.|\.\.)$/
100116
realpath = dpath + '\\' + d
101117
if session.fs.file.stat(realpath).directory?
102118
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)
105120
print_status(perm + "\t" + realpath)
106121
end
107-
enum_subdirs(realpath, maxdepth - 1,token)
122+
enum_subdirs(perm_filter, realpath, maxdepth - 1,token)
108123
end
109124
end
110125
end
111126
end
112127

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?
115131

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 []
119137
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]
125143
end
144+
end
126145

127-
#get impersonation token
146+
def get_token
128147
print_status("Getting impersonation token...")
129148
begin
130149
t = get_imperstoken()
@@ -134,19 +153,51 @@ def run
134153
vprint_error("Error #{e.message} while using get_imperstoken()")
135154
vprint_error(e.backtrace)
136155
end
156+
return t
157+
end
137158

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
144172

145-
is_path_valid = check_dir(path, t)
146-
if not is_path_valid.nil?
147173
#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)
149175
end
150176
end
151177
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
152203
end

0 commit comments

Comments
 (0)