Print Spooler CVE 2020-1030

https://www.accenture.com/us-en/blogs/cyber-defense/discovering-exploiting-shutting-down-dangerous-windows-print-spooler-vulnerability

Vulnerability Flow

  • By default, users can add printers without administrator authentication needed.

  • Calling AddPrinter returns a printer handle with the PRINTER_ALL_ACCESS right. This grants printing rights to standard and administrative print operations.

  • However, the caller of the AddPrinter function must have SERVER_ACCESS_ADMINISTER access to the server on which the printer is to be created.

  • An unprivileged user will not have these rights and hence, can't add a new printer with PRINTER_ALL_ACCESS right.

  • However, "INTERACTIVE" group has the maage server permissions enabled which corresponds to SERVER_ACCESS_ADMINISTER.

  • AddPrinter returns handle with PRINTER_ALL_ACCESS right.

  • We use this handle's permission to modify spool directory.

  • PRE: When a user prints a document, a print job is spooled to a predefined location referred to as the spool directory. It is writeable by all users (for printing of course) and this spool directory is configurable on each printer.

  • SetPrinterDataEx is a function that can be used to configure spool directory. However, to configure it, admin permission is needed. Lucky for us, we have a print handle that has this permission (PRINTER_ALL_ACCESS right)

  • The print spooler service must reinitialize for the spool directory to take effect. Unprivileges users can't do this by hook, so to do this by crook, they can do the following:

    • AppVTerminator.dll calls TerminateProcess function

    • This would terminate spoolsv.exe and will be immediately restarted (point and print behaviour)

  • Getting a handle on code execution: When the service initializes, the spool directory (spool\drivers\x64\4) is created with a SECURITY_DESCRIPTOR right granting all users with WriteData permission. This allows us to move our payload into the directory.

  • To obtain cod execution, we use OpenPrinter to request a handle to our existing printer object. SetPrinterDataEx is called once more to trigger Point and Print with our payload. our payload is then loaded into the existing running process spoolsv.exe using SpoolerCopyFileEvent function.

Demonstration

Last updated