Introduction
Printers present an interesting case in the world of Internet of Things (IoT), as they are very powerful hardware compared to most IoT devices, yet are not typically thought of as a “real” computer by most administrators. Over the years, many security researchers have studied and reported on printer vulnerabilities. However, the vast majority of this research focused on how to hack the printer itself in order to do things such as change the display on the printer or steal the documents that were printed. In this case, we investigate how to use the special role that printers have within most networks to actually infect end-user devices and extend the footprint of their attack within the network.
Background
To understand this issue, we need to understand a bit about Microsoft Web Point-and-Print Protocol (MS-WPRN) and why it works the way that it does.
Most organizations try to apply the principle of least privilege to the devices in their networks. This works pretty well for things like laptops or desktops since the hardware they use doesn’t change that often. However printers are a bit different. While they still need drivers, printers need to support virtually any user that wants to connect to them. As end-users move through a build, they naturally want to use the printer closest to them. Mobile users expect to be able to easily connect and use a printer when they come into the office. In addition, most organizations don’t standardize on a single printer, and will have multiple models and manufacturers often within a single network.
So instead of having system administrators push all possible printer drivers to all workstations in the network, the solution was to develop a way to deliver the driver to a user device right before the printer is used. And this is where Point-and-Print showed up. This approach stores a shared driver on the printer or print server, and only the users of that printer receive the driver that they need. At first glance, this is a practical and simple solution to driver deployment. The user gets access to the printer driver they need without requiring an administrator—a nice win-win.
The issue
The problem is that for this scheme to work nicely from an end-user perspective, an exception was required. Normally, User Account Controls are in place to warn or prevent a user from installing a new driver. To make printing easier, an exception was created to avoid this control. So in the end, we have a mechanism that allows downloading executables from a shared drive, and run them as system on a workstation without generating any warning on the user side. From an attacker perspective, this is almost too good to be true, and of course we had to give it a try.
The exploitation
In our case we are using a real printer. Since most printers are loaded with features, it was not too hard to find a bug that provided access to the underlying system. In this case, we were able to unpack a firmware update to gather some credentials and understand the file system layout. A binwalk magic file is provided in the Tools section at the end of this page, and after some digging we found the file related to those drivers. They need to be on a shared driver "print$" in smb, and typically include multiple flavors for various types of architecture (e.g. x86, x64, ppc, alpha). Look for directories named: W32X86, x64, IA64, color, etc.
We simply took the x86 dll file out of the printer, which can be done directly or through rpcclient[5], and patched it with "the-backdoor-factory"[1].
This gave us back a dll file with an injected payload inside of it.
Putting the dll back in the original directory could be done in multiple ways. You can typically write back to the print$ share if you have domain admin credential. Alternatively, with local root access to the printer you can overwrite the existing file with the backdoored one we just created. It's still amazing that vendors leave the default hidden credentials on the machine. If it's not in your cracking dictionary, it's always good to add root:myroot just in case.
In our example we used a mix of Windows XP 32bit, Windows 7 32bit, Windows 7 64 bit, Windows 2008 R2 AD 64, Ubuntu CUPS, Windows 2008 R2 64 print server and an unnamed printer. For Windows 7 to work nicely with Point-and-Print, it needed to be configure on the Active Directory side and pushed as a policy. A bit more about it in the Internet Printing Protocol section below.
After doing the normal add printer with auto discovery and selecting our printer (with the backdoored dll), the windows system goes through the normal driver acquisition and installation process.
This stage allow installation of a printer driver without any user warning, uac or even binary signature verification, and all under the system rights.
This gave us the following on the msfconsole side:
Other possible vectors
Given the nature of this issue, there are many ways that the remote code execution can be used. In the example above, we reverse engineered a desktop printer, but the same driver loading feature could be achieved with a different software stack and used in different scenarios. Some of those include but are not limited to:
- Watering hole attacks
- Backdooring an existing printer or printer server.
- Microsoft print server: driver path: c:\windows\system32\spool\drivers\*\3\...
- Linux cups server: check for share driver print$ in the configuration.
- Multiple vendors support Point-and-Printon the printer itself.
- Re-flash printer with backdoored drivers.
- Create a fake print server and broadcast with auto discovery.
- Privilege escalation
- Use the add printer as a privileged escalation mechanism to get system access.
- Mitm attack to the printer and inject the backdoored driver instead of the real one.
- Going more global with IPP and Webpnp.
Infecting remotely using Internet printing protocol and web PointNPrint
So far we have constrained ourselves to an internal network where a device was either inserted or infected and used to further infect devices connecting to it. Microsoft Internet printing protocol (IPP) and web pointNprint allow us to extend this issue outside the intranet to the internet. Microsoft IPP allow for the same mechanism to load driver from the printer. This can be done with following piece of code from the MS print server.
This url contain a file that is a ".webpnp" or webpointNprint.
Let's see the content of that nice 10MB binary file.
This is where the files that are going to be loaded reside. The files that we patched from the previous attack ran just as well whether delivered through smb,Point-and-Print, or under webpnp.
Root cause of the issue
Tracing the issue brings us to a ntprint.dll library, specifically around the function "PSetupDownloadAndInstallLegacyDriver". Specifically thisis the function responsible for checking the policy and performing the installation with elevated privilege.
While there are valid deployment reasons to want to allow driver install without administrator rights, a warning should probably always be enabled and binary signature should probably always be checked in an attempt to reduce the attack surface.
Remediations
Vectra and Microsoft collaborated during the investigation of this issue, and Microsoft has delivered a fix for CVE-2016-3238 (MS16-087), andCVE-2016-3239as part ofSecurity Bulletin MS16-087, which is available here.
The behavior of Point-and-Print can be defined with GPO to a level of granularity that should give admin control of the risk. While it's possible to disable Point-and-Print or to add a warning and request UAC, this just brings us back the first problem of how to manage the drivers so the user could install the driver without having to contact IT every time.
Microsoft provides the needed documentation at [3],[4], and development of enhancedPoint-and-Print(v4), attempts to remediate some of these issues. Migrating to a printer supporting the newest version of the protocol and newer version of windows could minimize a portion of the attack surface. We have not reviewed the security features of v4 / enhanced Point-and-Print further than their specification at this point, however backward compatibility might render those effort moot.
Checking your networks
Host registry for enablingPoint-and-Print
Scanning your network for Point n Print driver