The Ultimate Guide to PrintNightmare (and overcoming it)
Background and Timelines
Printing is something that most admins don’t want to think about. This tweet (which is a single picture) sums up most admins’ perspective about printers:
That being said, the original gory details of WHAT the vulnerability is, which include a privilege escalation and remote code execution can be found here: https://www.csoonline.com/article/3623760/printnightmare-vulnerability-explained-exploits-patches-and-workarounds.html
You can be forgiven for not wanting to go too too deep here. But the gist is: If the bad guys convinced your users to click on a thing, that would automatically install an “evil driver” which would then give the bad guy full admin access. I’m summarizing a little bit, but that’s the gist.
Essentially: you are / were open to attack and have to fix it.
Okay. Got it. So what does fixing it look like?
There’s three dates we have to take into consideration for the discussion:
Anything before July 6th.
Between July 6th and Aug 10.
Anything after Aug 10.
Let’s break down each date and method here.
Before July 6: How would you mitigate Printnightmare WITHOUT any patches
Microsoft’s recommendations which would at least “Shut the door” on possible attacks (BEFORE the July and Aug patches.)
Tip: These are / were PREVIOUS recommendations (applicable if you don’t have patches everywhere:
Completely disable the Print Spooler Service:
DCs because they’re important
Everywhere else because they’re important too.
Use the “Allow Print Spooler to accept client connections” and set to DISABLE. This will keep the the print spooler service running, but prevent REMOTE connections to the Print Spooler Service. And, moreover, it still works LOCALLY from the machine for local print jobs. It just prevents sharing printers for OTHER machines. This setting is actually a good mitigation on workstations, which in most cases do not need to share their printers with anyone else. Note that after this setting is deployed it requires a reboot of the system or at least a restart of the spooler service. (Thanks to Haemish Edgerton for the clarity adjustment here.)
You can use GPPrefs SERVICES or Powershell scripts or whatever to also do the same thing.
Now the print spooler services are stopped dead. Printing has now stopped.
Dateline: July 6th - The Patch Arrives
The July 6th patch seemed like it would get the problem solved. From the July patch notes: https://support.microsoft.com/en-us/topic/kb5005010-restricting-installation-of-new-printer-drivers-after-applying-the-july-6-2021-updates-31b91c02-05bc-4ada-a7ea-183b129578a7
After putting the July 6th patch everywhere, Microsoft ALSO suggested that you use “Point and print Restrictions” policy setting to force “Show warning and elevation prompt” as follows:
Setting the value to 0, or leaving the value undefined, allows non-administrators to install signed and unsigned drivers to a print server but does not override the Point and Print Group Policy settings. This is the default value. Consequently, the Point and Print Restrictions Group Policy setting can override this to allow non-administrators to be able to install signed and unsigned print drivers to a print server.
But one day later, this was overcome with some example code. Here’s the original tweet and video: https://twitter.com/gentilkiwi/status/1412771368534528001
Ack ! Back to Printnightmare and re-shut down all print servers ! OMG.. run for the hills !
Now the print spooler services are stopped dead. Printing has now stopped.
Dateline: Aug 10 - Patch 2 is released (Aka Slam the door shut / no more non-admin access for Print Drivers.)
That’s it, no more Mr. Nice guy. Microsoft decides to go nuclear at this problem. They release another Patch for Aug 10.
Changes the default privilege requirement for installing drivers when using Point and Print. After installing this update, you must have administrative privileges to install drivers.
You need to be a local admin to do anything Printer-y. Technically this was already true; as standard users could never install, say, local print drivers from some unusual source.
Users who are used to finding printers by the Click to Print method are simply blocked at showtime.
Now, there’s a little SIDE NOTE here (Tip of the Hat to Hasain Alshakarti from TRUESEC security @Alshakarti). The door MAY NOT EVEN BE COMPLETELY SHUT. MS released CVE-2021-36958 Aug 11, 2021 that describes the LPE/RCE Windows Print Spooler Remote Code Execution Vulnerability. Depending on the version of the driver the elevation prompt is not triggering as shown by Benjamin Delphi as seen here https://twitter.com/gentilkiwi/status/1425154484167188480
Here’s what it looks like (in pictures, not a video) when a user attempts to click to print on a printer (where the drivers have never been installed).
Step 1: Find the printer and get initial prompt
Step 2: Final prompt requiring local admin access to proceed
So, the August 10th patch really did close the door for the good guys.
Now what? How do we let them back in?
Now that the door is shut, how do we open it for SOME people?
So first thing’s first. If the spooler is stopped by ANY of those original methods above, then, nothing else is ever going to work. You’ll have to back out any change which killed the printer spooler.
Then, after that I’ve rounded up a few POSSIBLE workarounds. Some anecdotally and others from Microsoft’s guidance here (https://support.microsoft.com/en-gb/topic/kb5005652-manage-new-point-and-print-default-driver-installation-behavior-cve-2021-34481-873642bf-2634-49c5-a23b-6d8e9a302872) which we’ll review in a bit.
Additionally, I want to show how there’s also a slew of other workarounds if you happen to be a PolicyPak Customer. I’ll field these at the end.
Tip 1: Just keep using Group Policy Preferences to deliver printers to those who need it. (Maybe. Will likely work.)
So this whole Printnightmare is basically trying to solve the problem of a user making a choice where to print (and that vector being insecure.)
But there isn’t any problem with real admins making choices to deliver printers via Group Policy Preferences (even after the patches are in place.) That still works. Sure, I realize this is a little “Apples and Oranges.” Because GP Preferences is not “Click to Print”.
But if you could use Group Policy Preferences to mass-deliver printers like this to your domain-joined machines, you could still be a-ok. Here’s an example.
Note there still can be problems. If the server is 2016 (or OLDER, like 2012, 2012R2)... and the drivers are “v3” drivers, then… users are still prompted to re-install them as admins. Gah ! The workaround is to upgrade your server’s print drivers to v4 drivers if they are available (which, there may not be.)
Tip: If you want to see what version of the drivers you're using, on a target machine run the Print Manager utility (again, this is on the endpoint where you already use the printers.) Then, see this column to determine driver type.
The details are documented here by MVP Susan Bradley (@susanbradley): https://www.computerworld.com/article/3630629/windows-print-nightmare-continues-enterprise.html
I’ll update this space if there’s more on this story.
Tip 2 (which didn’t work for me): Use Point and Print Restrictions to specify the GOOD servers
I mention this tip, because it really looks like it SHOULD work, but just.. Doesn’t. Read thru it anyway, because we’ll make some lemonade out of lemons here in a minute.
Maybe this worked AFTER the July patch but stopped working AFTER the August patch but I didn’t expressly test that.
The idea would be to simply specify the GOOD servers, so the user wouldn’t be able to print to any BAD servers. Example configuration below (again, doesn’t work) which would specify the servers, but then also NOT prompt for elevation.
Microsoft’s text says:
NoWarningNoElevationOnInstall = 0 (DWORD) or not defined (default setting)
UpdatePromptSettings = 0 (DWORD) or not defined (default setting)
NoWarningNoElevationOnInstall set to 1 makes your system vulnerable by design.
The result on endpoints would be something like this..
Again: This proposed workaround did not work for me, your experience might be different.
If I was asked how to solve this problem within Microsoft engineering, this is how I would have proposed to do it: Specify ONLY the good servers and make it so Standard Users couldn’t make changes from that list.
Mayyyybe Microsoft will fix the problem (again) this way, but no signs yet.
Tip 2 (From Microsoft): “Just screw it” and let Standard Users do whatever they want anyway (NOT RECOMMENDED)
So, of course it sounds like, and would be a terrible idea to just turn off the new August 10th protection, even after you’re patched. If you wanted to do that, the advantage of course is that Standard Users could click to print on whatever servers they wanted. Which of course, would also be bad if the bad guys used this against you.
This tested out a-ok as you can see here.
Again, not a great idea, but it does work, even if the August patch is on the machine.
Tip 3: Combine (non-working) Tip 2 and (working) Tip 3 to attempt to make something (reasonably) secure
So Tip 2 where we specified the GOOD server didn’t work. And Tip 3 where we specified that non-admins could overcome this driver thing… that worked.
I’m trying here to specify a SPECIFIC server that’s good, and therefore everything else is bad.
I’m then using the special bypass registry key to let non-admins install the drivers.
This should work, right ?
Let’s break it down.
Well, this works when 100% by itself. If I attempt to connect to some rogue server, I do get blocked. Yay.
But then when I add the bypass registry item…. It doesn’t work.. YET !
So far, this is equally bad as just letting non-admins install their own drivers.
The secret to making this work is a SECOND setting, which expresses where the “Package Point and print - Approved servers” are.
Then, I get the basic / final / good result I want:
Non-Admins can point to good “specified” servers
Non-Admins cannot point to rogue servers
Even though I showed how to do this, Microsoft does go out of their way to say : “Important There is no combination of mitigations that is equivalent to setting RestrictDriverInstallationToAdministrators to 1.”
I don’t know exactly what the differences are between the super secure admin only method and the “open the doggie door to the right people” method I just stepped though, and maybe Microsoft doesn’t want us to know. :-)
Okay: Really, what are some OTHER SECURE workarounds?
First of all the method I showed above is only “OK” because Microsoft stated that you aren’t really in a totally secure state. The second problem with the method I showed is that you have to keep on top of your print servers all the time and update the TWO policy settings to accommodate. Maybe this is fine in a small or static environment. Or maybe this could get out of hand quickly.
Solid Workaround 1: Using PolicyPak Least Privilege Manager + Printer Helper Tool
I’m going to jump RIGHT TO THE END, and tell you what I think is the ideal solution problem, and, sorry to say, this is not a free solution. And, I’m the founder and CTO of the solution, so, maybe I’m a little biased.
But in short, here’s a video where you can use PolicyPak Least Privilege Manager to elevate the installation of printers on any server, while the person is a standard user.
Why is this the best method?
First, you don’t have to enable this for all users; just the users who need to do this from time to time.
Second, you don’t need to really be opening up admin rights everywhere; it’s just for this key case.
Third, it quacks like the native tool, but does require one click to get it started, instead of “Print to click.”
And lastly, this technique also works for installing LOCAL printers, which might also come in handy.
This also dovetails nicely into the whole “Zero Trust” model. Let only the users who need this technique get this technique. Remove local admin rights and reduce your attack surface.
Solid Workaround 2: Pre-install the drivers to the machine (somehow)
If you are able to magically pre-install the drivers into the machine’s local cache then you get a hall pass here.
You can do this in your image, or, if you already have 10,000 machines out there, you can script your way to glory.
Tip of the hat to my friends at PDQ for the inspiration for this tip. You can find their lashup here: https://www.pdq.com/blog/using-powershell-to-install-printers/
The idea I tested manually, worked awesome, as you can see here. The gist is to use PNPUtil to get the drivers pre-installed as an admin. Then the user can click on the network printer and they’re done. No prompts. It just works.
There’s another method that I found, which involves getting a machine prepped with all your drivers and backing up the driver store and preparing them as a “package.” Printbrm.exe and PrintbrmUI.exe are the in-box utilities which do this. A good write up if you want to do this is here (https://lakeforestconsulting.com/adminprintnightmare/). You can then deploy the package using SCCM, Intune, PolicyPak or another method of your choice.
Solid Workaround 3: Use the same printer driver as many times as you can
I found this one from here: https://community.spiceworks.com/topic/2328739-best-way-to-deploy-printnightmare-proof-printers-to-non-admin-users?page=1#entry-9250842 (Courtesy https://community.spiceworks.com/people/ethanharris). I’ll just quote him and make this easier for everyone:
“We get around it by using the same universal HP driver on our print server for all black & white printing. Since they already have the print driver installed they get no admin prompt when they add other printers.
For each color printer we create two printers on the print server, "PrinterName" and "PrinterName-Color" with the actual driver for that printer model used on the -Color version. It is understood by staff that anyone can add a printer to print in B&W but IT needs to enter the admin password if they need to add a printer to print in color. This also helps to cut down on printing costs as color printing costs 10x as much as B&W on our printing contract.“
Are there Workarounds if I’m not domain joined?
Yes, Here’s the others I’m able to come up with. If you have more to add, let me know and I’ll add them here and give you credit.
Using an MDM Service + PowerShell
If you use an MDM service like Intune, then you could use the script method from the PDQ guys (see above). That’s a little more than I want to get into here, but it should get you near the goal.
Using PolicyPak + Least Privilege Manager
I already mentioned the Least Privilege Manager and the Helper Tool; here's a link to an alternate video which shows a few more magic tricks of the Helper Tools.
Using PolicyPak + Remote Work Delivery Manager
We’ve had this KB around for a while; but it works great to overcome Printnightmare. The gist is that you copy install files from, say, Dropbox, Amazon S3 or Azure storage, then script the install.
Using PP Scripts to Deploy Printers for Users (so they don’t have to.)
This method is similar to the PP + REmote Work Delivery Manager Method, but could be useful if you only have PP Scripts and Triggers and not Remote Work Delivery Manager.
Using PolicyPak Cloud + GPPRefs TCPIP Printers
This could help some people, so I’m adding it here.
Final thoughts about Printnightmare
The world is heading toward Zero Trust. Which means every piece of the network needs (or should have) explicit allow rules.
We believe in this idea at PolicyPak, and can do blocking by default for regular downloads, Windows Store downloads, and even block stuff on USB sticks.
With the Printnightmare patch, they are basically saying the same thing: trust no one but your admins. But if you give someone local admin rights on the box, you’re shooting yourself in the foot.
Remove local admin rights and get to Least Privilege land (using PolicyPak Least Privilege Manager). And then give back what you need to with rules to open up specific admin-like-things to your end-users (like adding printers) as needed.
Hope this guide helps you out.