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_powershell_env.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::File
8
include Msf::Post::Windows::Priv
9
include Msf::Post::Windows::Registry
10
11
def initialize(info = {})
12
super(
13
update_info(
14
info,
15
'Name' => 'Windows Gather PowerShell Environment Setting Enumeration',
16
'Description' => %q{ This module will enumerate Microsoft PowerShell settings. },
17
'License' => MSF_LICENSE,
18
'Author' => [ 'Carlos Perez <carlos_perez[at]darkoperator.com>'],
19
'Platform' => [ 'win' ],
20
'References' => [
21
['URL', 'https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_execution_policies'],
22
['URL', 'https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_profiles'],
23
],
24
'SessionTypes' => %w[meterpreter shell powershell],
25
'Notes' => {
26
'Stability' => [CRASH_SAFE],
27
'Reliability' => [],
28
'SideEffects' => []
29
},
30
'Compat' => {
31
'Meterpreter' => {
32
'Commands' => %w[
33
core_channel_eof
34
core_channel_open
35
core_channel_read
36
core_channel_write
37
stdapi_sys_config_getenv
38
stdapi_sys_config_getuid
39
]
40
}
41
}
42
)
43
)
44
end
45
46
def enum_users
47
users = []
48
49
system_drive = get_env('SystemDrive').to_s.strip
50
51
path4users = ''
52
if directory?("#{system_drive}\\Users")
53
path4users = "#{system_drive}\\Users\\"
54
profilepath = '\\Documents\\WindowsPowerShell\\'
55
elsif directory?("#{system_drive}\\Documents and Settings")
56
path4users = "#{system_drive}\\Documents and Settings\\"
57
profilepath = '\\My Documents\\WindowsPowerShell\\'
58
else
59
print_error('Could not find user profile directories')
60
return []
61
end
62
63
if is_system? || is_admin?
64
print_status('Running with elevated privileges. Extracting user list ...')
65
paths = begin
66
dir(path4users)
67
rescue StandardError
68
[]
69
end
70
71
ignored = [
72
'.',
73
'..',
74
'All Users',
75
'Default',
76
'Default User',
77
'Public',
78
'desktop.ini',
79
'LocalService',
80
'NetworkService'
81
]
82
paths.reject { |p| ignored.include?(p) }.each do |u|
83
users << {
84
'username' => u,
85
'userappdata' => path4users + u + profilepath
86
}
87
end
88
else
89
u = get_env('USERNAME')
90
users << {
91
'username' => u,
92
'userappdata' => path4users + u + profilepath
93
}
94
end
95
96
users
97
end
98
99
def enum_powershell_modules
100
powershell_module_path = get_env('PSModulePath')
101
return [] unless powershell_module_path
102
103
paths = powershell_module_path.split(';')
104
print_status('PowerShell Modules paths:')
105
modules = []
106
paths.each do |p|
107
print_status("\t#{p}")
108
109
path_contents = begin
110
dir(p)
111
rescue StandardError
112
[]
113
end
114
path_contents.reject { |m| ['.', '..'].include?(m) }.each do |m|
115
modules << m
116
end
117
end
118
119
modules
120
end
121
122
def enum_powershell
123
unless registry_enumkeys('HKLM\\SOFTWARE\\Microsoft').include?('PowerShell')
124
print_error('PowerShell is not installed on this system.')
125
return
126
end
127
128
print_status('PowerShell is installed on this system.')
129
130
powershell_version = registry_getvaldata('HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1\\PowerShellEngine', 'PowerShellVersion')
131
print_status("Version: #{powershell_version}")
132
133
powershell_policy = begin
134
registry_getvaldata('HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1\\ShellIds\\Microsoft.PowerShell', 'ExecutionPolicy')
135
rescue StandardError
136
'Restricted'
137
end
138
print_status("Execution Policy: #{powershell_policy}")
139
140
powershell_path = registry_getvaldata('HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1\\ShellIds\\Microsoft.PowerShell', 'Path')
141
print_status("Path: #{powershell_path}")
142
143
if registry_enumkeys('HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1').include?('PowerShellSnapIns')
144
print_status('PowerShell Snap-Ins:')
145
registry_enumkeys('HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1\\PowerShellSnapIns').each do |si|
146
print_status("\tSnap-In: #{si}")
147
registry_enumvals("HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1\\PowerShellSnapIns\\#{si}").each do |v|
148
print_status("\t\t#{v}: #{registry_getvaldata("HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1\\PowerShellSnapIns\\#{si}", v)}")
149
end
150
end
151
else
152
print_status('No PowerShell Snap-Ins are installed')
153
end
154
155
modules = enum_powershell_modules
156
if modules && !modules.empty?
157
print_status('PowerShell Modules:')
158
modules.each do |m|
159
print_status("\t#{m}")
160
end
161
else
162
print_status('No PowerShell Modules are installed')
163
end
164
165
profile_file_names = [
166
'profile.ps1',
167
'Microsoft.PowerShell_profile.ps1',
168
'Microsoft.VSCode_profile.ps1',
169
]
170
171
print_status('Checking if users have PowerShell profiles')
172
enum_users.each do |u|
173
print_status("Checking #{u['username']}")
174
175
app_data_contents = begin
176
dir(u['userappdata'])
177
rescue StandardError
178
[]
179
end
180
app_data_contents.map!(&:downcase)
181
182
profile_file_names.each do |profile_file|
183
next unless app_data_contents.include?(profile_file.downcase)
184
185
fname = "#{u['userappdata']}#{profile_file}"
186
187
ps_profile = begin
188
read_file(fname)
189
rescue StandardError
190
nil
191
end
192
next unless ps_profile
193
194
print_status("Found PowerShell profile '#{fname}' for #{u['username']}:")
195
print_line(ps_profile.to_s)
196
end
197
end
198
end
199
200
def run
201
hostname = sysinfo.nil? ? cmd_exec('hostname') : sysinfo['Computer']
202
print_status("Running module against #{hostname} (#{session.session_host})")
203
enum_powershell
204
end
205
end
206
207