Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/post/windows/gather/enum_dirperms.rb
19758 views
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Post
7
include Msf::Post::Windows::Accounts
8
9
def initialize(info = {})
10
super(
11
update_info(
12
info,
13
'Name' => 'Windows Gather Directory Permissions Enumeration',
14
'Description' => %q{
15
This module enumerates directories and lists the permissions set
16
on found directories. Please note: if the PATH option isn't specified,
17
then the module will start enumerate whatever is in the target machine's
18
%PATH% variable.
19
},
20
'License' => MSF_LICENSE,
21
'Platform' => ['win'],
22
'SessionTypes' => ['meterpreter'],
23
'Author' => [
24
'Kx499',
25
'Ben Campbell',
26
'sinn3r'
27
],
28
'Notes' => {
29
'Stability' => [CRASH_SAFE],
30
'SideEffects' => [],
31
'Reliability' => []
32
},
33
'Compat' => {
34
'Meterpreter' => {
35
'Commands' => %w[
36
stdapi_fs_stat
37
]
38
}
39
}
40
)
41
)
42
43
register_options(
44
[
45
OptString.new('PATH', [ false, 'Directory to begin search from', '']),
46
OptEnum.new('FILTER', [ false, 'Filter to limit results by', 'NA', [ 'NA', 'R', 'W', 'RW' ]]),
47
OptInt.new('DEPTH', [ true, 'Depth to drill down into subdirs, O = no limit', 0]),
48
]
49
)
50
end
51
52
def enum_subdirs(perm_filter, dpath, maxdepth, token)
53
begin
54
dirs = session.fs.dir.foreach(dpath)
55
rescue Rex::Post::Meterpreter::RequestError
56
# Sometimes we cannot see the dir
57
dirs = []
58
end
59
60
if (maxdepth >= 1) || (maxdepth < 0)
61
dirs.each do |d|
62
next if d =~ /^(\.|\.\.)$/
63
64
realpath = dpath + '\\' + d
65
next unless session.fs.file.stat(realpath).directory?
66
67
perm = check_dir_perms(realpath, token)
68
if perm_filter && perm && perm.include?(perm_filter)
69
print_status(perm + "\t" + realpath)
70
end
71
enum_subdirs(perm_filter, realpath, maxdepth - 1, token)
72
end
73
end
74
end
75
76
def get_paths
77
p = datastore['PATH']
78
return [p] if !p.nil? && !p.empty?
79
80
begin
81
p = cmd_exec('cmd.exe', '/c echo %PATH%')
82
rescue Rex::Post::Meterpreter::RequestError => e
83
vprint_error(e.message)
84
return []
85
end
86
print_status("Option 'PATH' isn't specified. Using system %PATH%")
87
if p.include?(';')
88
return p.split(';')
89
else
90
return [p]
91
end
92
end
93
94
def get_token
95
print_status('Getting impersonation token...')
96
begin
97
t = get_imperstoken
98
rescue StandardError => e
99
# Failure due to timeout, access denied, etc.
100
t = nil
101
vprint_error("Error #{e.message} while using get_imperstoken()")
102
vprint_error(e.backtrace)
103
end
104
return t
105
end
106
107
def enum_perms(perm_filter, token, depth, paths)
108
paths.each do |path|
109
next if path.empty?
110
111
path = path.strip
112
113
print_status("Checking directory permissions from: #{path}")
114
115
perm = check_dir_perms(path, token)
116
next if perm.nil?
117
118
# Show the permission of the parent directory
119
if perm_filter && perm.include?(perm_filter)
120
print_status(perm + "\t" + path)
121
end
122
123
# call recursive function to loop through and check all sub directories
124
enum_subdirs(perm_filter, path, depth, token)
125
end
126
end
127
128
def run
129
perm_filter = datastore['FILTER'] == 'NA' ? nil : datastore['FILTER']
130
131
paths = get_paths
132
if paths.empty?
133
print_error('Unable to get the path')
134
return
135
end
136
137
depth = -1
138
if datastore['DEPTH'] > 0
139
depth = datastore['DEPTH']
140
end
141
142
t = get_token
143
144
if t
145
print_status("Got token: #{t}...")
146
enum_perms(perm_filter, t, depth, paths)
147
else
148
print_error('Getting impersonation token failed')
149
end
150
end
151
end
152
153