PrintNightmare Module False Positives
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:
Screenshots
Initial Detection:
Manual Confirmation of System Patch
Manual Confirmation of Associated Registry Key Fixes
NetExec info
- OS: Arch Linux
- Version of nxc: Latest
- Installed from: pipx
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?