NetExec icon indicating copy to clipboard operation
NetExec copied to clipboard

PrintNightmare Module False Positives

Open Mercury0 opened this issue 8 months ago • 1 comments

Describe the bug On a recent engagement I used the printnightmare SMB module which incorrectly identified a vulnerable system. After using a privileged account to hop onto the system, I confirmed that although the Print Spooler service was running, security updates had been applied which prevent the exploitation of this vulnerability. Additionally, the NoWarningOnElevationOnInstall registry key exists and is set to 0 (as it should be) per Microsoft's guidance.

The module currently detects the vulnerability by connecting to spoolss service, binding to the MS-RPRN interface, and making an RpcAddPrinterDriverEx call with a crafted DRIVER_CONTAINER structure as a non-privileged user. If this call returns ERROR_INVALID_PARAMETER (0x57), it flags the system as vulnerable. A return value of RPC_E_ACCESS_DENIED (0x8001011B) is used to to decide if a system is not vulnerable.

[lines 87 - 112]

try:
            hRpcAddPrinterDriverEx(
                dce,
                pName=NULL,
                pDriverContainer=driver_container,
                dwFileCopyFlags=flags,
            )
        except DCERPCSessionError as e:
            # RPC_E_ACCESS_DENIED is returned on patched systems, when
            # a non-administrative user tries to create a new printer
            # driver
            if e.error_code == RPC_E_ACCESS_DENIED:
                context.log.info("Not vulnerable :'(")
                return False
            # If vulnerable, 'ERROR_INVALID_PARAMETER' will be returned
            if e.error_code == system_errors.ERROR_INVALID_PARAMETER:
                context.log.highlight("Vulnerable, next step https://github.com/ly4k/PrintNightmare")
                return True
            context.log.fail(f"Unexpected error: {e}")
        except DCERPCException as e:
            if rpc_status_codes[e.error_code] == "rpc_s_access_denied":
                context.log.info("Not vulnerable :'(")
                return False
            context.log.fail(f"Unexpected error: {e}")
        context.log.highlight("Vulnerable, next step https://github.com/ly4k/PrintNightmare")
        return True

Expected behavior Expected behavior is to apply additional checking to increase our confidence in detecting a vulnerable system and minimize false positives. The current logic could be used for "presumptive" identification, with additional logic implemented to confirm exploitability by checking for the presence of system patches which prevent exploitation + querying the below registry keys which are associated with resolving this CVE:

Image

Screenshots

Initial Detection:

Image

Manual Confirmation of System Patch

Image

Manual Confirmation of Associated Registry Key Fixes

Image

NetExec info

  • OS: Arch Linux
  • Version of nxc: Latest
  • Installed from: pipx

Mercury0 avatar Jun 06 '25 16:06 Mercury0

Thanks for the report! However, checking registry keys is likely only possible with having admin privs on the target host. Any idea if/how we could check if it was patched without the need to query registry keys?

NeffIsBack avatar Jun 12 '25 10:06 NeffIsBack