CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/post/windows/gather/enum_dirperms.rb
Views: 11655
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
'Compat' => {
29
'Meterpreter' => {
30
'Commands' => %w[
31
stdapi_fs_stat
32
]
33
}
34
}
35
)
36
)
37
38
register_options(
39
[
40
OptString.new('PATH', [ false, 'Directory to begin search from', '']),
41
OptEnum.new('FILTER', [ false, 'Filter to limit results by', 'NA', [ 'NA', 'R', 'W', 'RW' ]]),
42
OptInt.new('DEPTH', [ true, 'Depth to drill down into subdirs, O = no limit', 0]),
43
]
44
)
45
end
46
47
def enum_subdirs(perm_filter, dpath, maxdepth, token)
48
filter = datastore['FILTER']
49
filter = nil if datastore['FILTER'] == 'NA'
50
51
begin
52
dirs = session.fs.dir.foreach(dpath)
53
rescue Rex::Post::Meterpreter::RequestError
54
# Sometimes we cannot see the dir
55
dirs = []
56
end
57
58
if (maxdepth >= 1) || (maxdepth < 0)
59
dirs.each do |d|
60
next if d =~ /^(\.|\.\.)$/
61
62
realpath = dpath + '\\' + d
63
next unless session.fs.file.stat(realpath).directory?
64
65
perm = check_dir_perms(realpath, token)
66
if perm_filter && perm && perm.include?(perm_filter)
67
print_status(perm + "\t" + realpath)
68
end
69
enum_subdirs(perm_filter, realpath, maxdepth - 1, token)
70
end
71
end
72
end
73
74
def get_paths
75
p = datastore['PATH']
76
return [p] if !p.nil? && !p.empty?
77
78
begin
79
p = cmd_exec('cmd.exe', '/c echo %PATH%')
80
rescue Rex::Post::Meterpreter::RequestError => e
81
vprint_error(e.message)
82
return []
83
end
84
print_status("Option 'PATH' isn't specified. Using system %PATH%")
85
if p.include?(';')
86
return p.split(';')
87
else
88
return [p]
89
end
90
end
91
92
def get_token
93
print_status('Getting impersonation token...')
94
begin
95
t = get_imperstoken
96
rescue ::Exception => e
97
# Failure due to timeout, access denied, etc.
98
t = nil
99
vprint_error("Error #{e.message} while using get_imperstoken()")
100
vprint_error(e.backtrace)
101
end
102
return t
103
end
104
105
def enum_perms(perm_filter, token, depth, paths)
106
paths.each do |path|
107
next if path.empty?
108
109
path = path.strip
110
111
print_status("Checking directory permissions from: #{path}")
112
113
perm = check_dir_perms(path, token)
114
next if perm.nil?
115
116
# Show the permission of the parent directory
117
if perm_filter && perm.include?(perm_filter)
118
print_status(perm + "\t" + path)
119
end
120
121
# call recursive function to loop through and check all sub directories
122
enum_subdirs(perm_filter, path, depth, token)
123
end
124
end
125
126
def run
127
perm_filter = datastore['FILTER']
128
perm_filter = nil if datastore['FILTER'] == 'NA'
129
130
paths = get_paths
131
if paths.empty?
132
print_error('Unable to get the path')
133
return
134
end
135
136
depth = -1
137
if datastore['DEPTH'] > 0
138
depth = datastore['DEPTH']
139
end
140
141
t = get_token
142
143
if t
144
print_status("Got token: #{t}...")
145
enum_perms(perm_filter, t, depth, paths)
146
else
147
print_error('Getting impersonation token failed')
148
end
149
end
150
end
151
152