Breaking Barriers and Assumptions: Techniques for Privilege Escalation on Windows: Part 3

August 01, 2024 | Michael DePlante and Nicholas Zubrisky

To wrap up this blog series we wanted to include one more technique that you can use when exploiting this class of vulnerabilities. This technique, introduced to us by Abdelhamid Naceri, becomes useful when you have an on-boot arbitrary delete primitive that you want to transform into an on-demand delete, so that you can escalate using the C:\Config.msi technique.  We will also share a tool that can make debugging protected processes on Windows easier and end by detailing some difficulties we faced during disclosures with several vendors.


Technique ++

One way you can use an on-boot delete primitive is to abuse the Windows Task Scheduler included in default installations of Windows. The Task Scheduler uses the following two directories to perform tasks:

C:\Windows\System32\Tasks - for standard task management.
C:\Windows\Tasks - for legacy operations aimed at ensuring compatibility with Windows XP.

When removing a task, the Task Scheduler does not validate mount points before it deletes the corresponding .job file from C:\Windows\Tasks. The DACL on C:\Windows\Tasks allows writing by a standard user. To prevent a user from taking advantage of this to convert C:\Windows\Tasks into a junction, Windows places a hidden SA.DAT file in this directory, so that the directory will not be empty. Exploiting this setup, it’s possible to transform a controlled boot-time deletion into an on-demand file deletion by removing the SA.DAT file. After deleting this file, the directory is empty, so it can be converted into a junction. Afterwards, deletion of the .job file can be redirected to C:\Config.Msi::$INDEX_ALLOCATION. Despite the directory being emptied of the .job file, Windows still believes this file is present in the tasks folder when we trigger the deletion of the task in our exploit. This is because task information is stored and managed in the Windows registry under the TaskCache key:

Below is a demonstration of this technique that we used to exploit a vulnerability we found in Papercut NG/MF Windows servers. The specific issue was within the PaperCut Web Print service which performed privileged delete operations in `C:\Windows\TEMP\web-print` when this service was started. This directory is typically used to store temporary files that are queued for printing. In the case of a system crash or other unexpected service shutdown, this directory has the potential to take up significant amounts of disk space. The service's delete-on-startup feature is intended to remove these temporary files that are no longer needed. However, this service never verifies any of the items it attempts to delete. So, by placing junctions inside this directory we can abuse this service to delete the contents of arbitrary directories on startup.

Making life a little easier

A common problem throughout this research project that we ran into occurred when we wanted to know more about a file operation that some application was performing. We’d double-click on the operation in Procmon, navigate to the stack trace tab, and be shown something like this:

Although we could see some of the calls that happened in the kernel, all other calls were unknown. This means we often could not find what binary or module was responsible for the file operations or what function that code was calling. We ran into this problem because the antivirus products we were looking at were running as protected processes. What this means is that these processes cannot be debugged, terminated, or inspected at all from a non-protected process, even if the user requesting to do any of these things is running as NT AUTHORITY\SYSTEM.

One can get around this by setting up a kernel debugging session, but this approach can be quite time-consuming. So instead, we used another technique. Since these protected processes cannot be viewed by a normal process, we simply need to turn our non-protected process into a protected one! This can be done using a tool such as PPLcontrol which uses a vulnerable driver to allow for arbitrary read and write access to kernel memory, which can be used to set arbitrary protection levels for any process. We have conveniently borrowed this functionality to create our own simple tool which will allow us to launch any process as a protected process. When we launch Procmon again as a protected process, we can finally see what all those unknowns are:

This tool also allows for a convenient way to debug a protected process. By launching WinDbg as a protected process, or a debugging server, we are now able to attach and debug protected processes. You can download this tool here. You can learn more and find additional resources about debugging protected processes here

Vendor Vertigo - A Few Examples of Difficult Disclosures

ZDI’s goal is always to get bugs patched and disclosed properly. We do our best to work with vendors to meet this goal. We recently published a separate blog that highlighted the ongoing erosion of trust between vendors and researchers that we have seen firsthand through our program. In this section, we will provide more context to illustrate the scope of this problem collected throughout this project.

Intel Corporation

An anonymous external researcher submitted several link following vulnerabilities in Intel's software that we ended up having to disclose without a patch.

We submitted the first case to them on 09/13/2023. The next day they responded to us with the following:

“We are rejecting this issue. After reviewing the information provided in this report, the Intel PSIRT team has determined that this report is out of scope of the Intel® Bug Bounty Program and therefore is not eligible for rewards. Symlinks are an Windows OS feature that are not managed by Intel Software.

For more details about symlink vulnerabilities see https://msrc.microsoft.com/update-guide/en-US/vulnerability/CVE-2019-1074

Best Regards,
Intel PSIRT”

After they sent this, we wrote back that same day with a detailed explanation of why this should be remediated alongside several published examples. It is also worth noting that the ZDI never requests or collects bug bounties from vendors. We didn’t receive a response back. 

Timeline:

09/13/23 – ZDI reported the vulnerability to the vendor.
09/14/23 – The vendor states they are rejecting the case as it is out of the scope of the Intel Bug Bounty Program.
09/14/23 – ZDI provided additional details on why this vulnerability should be remediated and that we intend to publish the case as a zero-day advisory on 09/21/23. -- Mitigation: Given the nature of the vulnerability, the only salient mitigation strategy is to restrict interaction with the application.
09/21/23 - No response from Vendor. ZDI publishes zero-day advisory.

Two weeks later, the second case followed the timeline below:

10/03/23 – ZDI reported the vulnerability to the vendor.
10/04/23 – Vendor acknowledges the report and said they are reviewing the case.
11/27/23 – The vendor states they are rejecting the case because it is a duplicate.
11/28/23 – The vendor sends an additional email that states " Symlinks are an Windows OS feature that are not managed by Intel Software”.
12/05/23 – ZDI again provided additional details on why this vulnerability should be remediated and that we intend to publish the case as a zero-day advisory on 12/12/23.
12/06/23 – The vendor requests when and where ZDI plans to disclose the vulnerability.
12/12/23 – ZDI publishes zero-day advisory.

These two cases with Intel emphasize a serious disconnect and apparent lack of commitment to understanding and addressing critical issues in their software.

PaperCut

If you are not familiar with PaperCut, their software is deployed to manage printing in various sectors including academia, healthcare, and government. Their website strongly emphasizes security, mentioning it several times on their website’s landing page. To their credit, they have been proactive in patching all the vulnerabilities we have reported to them thus far.

However, we have encountered alarming issues with PaperCut's handling of vulnerability disclosures. Despite our efforts to provide comprehensive evidence and detailed explanations during calls and email exchanges, PaperCut has chosen to downplay the severity and number of vulnerabilities in its publications. In a call with them over a year ago, they explained that any vulnerability with a severity above 7.0 requires them to notify government bodies, which then issue alerts to the public. To avoid this obligation, PaperCut appears to have misrepresented these vulnerabilities.

As shown in the following screenshot, they have chosen to condense and categorize four vulnerabilities that include various vulnerability types with different impacts into two CVEs. These CVEs were given the same incorrect CVSS score and assigned to our cases based on whether triggering the bug will create or delete files on the system. This short-sighted and negligent approach leaves the public blind to the real impact of the reported vulnerabilities.

It is worth noting that the advisory also mentions that “This vulnerability only applies to PaperCut NG/MF Windows servers with the PaperCut Web Print Server service enabled.” In our testing this service is enabled by default, so we were immediately confused as to why they mentioned this as if it was not enabled by default. When scrolling to the bottom of the page we find that they have included the following mitigation guidance:

In another case from the year prior, the verbiage in the advisory shows they understand that the attacker only requires low privileged code execution to escalate, and yet they still mark the CVSS as PR:H:

The concern is that vendors are minimizing critical issues and not adequately warning users about the associated risks. Unfortunately, vendors are doing this to maintain their image and circumvent legal reporting requirements. This practice undermines the intended purpose of vulnerability reporting while misleading users.

Below are the associated cases that we sent to Papercut that are mentioned in the above advisories:

ZDI-CAN-23859: PaperCut NG Directory Traversal Local Privilege Escalation Vulnerability
CVSS 3: AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H (7.8)

ZDI-CAN-24042: PaperCut NG Link Following Local Denial-of-Service Vulnerability
CVSS 3: AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:H (6.1)

ZDI-CAN-23757: PaperCut NG web-print-hot-folder Link Following Local Privilege Escalation Vulnerability
CVSS 3: AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H (7.8)

ZDI-CAN-20972: PaperCut NG pc-web-print Link Following Local Privilege Escalation Vulnerability
CVSS 3: AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H (7.8)

ZDI-CAN-21500: PaperCut NG Uncontrolled Search Path Element Local Privilege Escalation Vulnerability
CVSS 3: AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H (7.0)

Discoveries

As a result of the work shown in this blog series, we have discovered and disclosed the following vulnerabilities that have now been patched:

CVE-2024-3037, PaperCut NG web-print-hot-folder Link Following Local Privilege Escalation Vulnerability
CVE-2024-4454, WithSecure Elements Endpoint Protection Link Following Local Privilege Escalation Vulnerability
CVE-2024-2003, ESET Smart Security Premium Link Following Local Privilege Escalation Vulnerability
CVE-2024-0353, ESET Smart Security Premium ekrn Link Following Local Privilege Escalation Vulnerability
CVE-2024-3037, PaperCut NG pc-web-print Link Following Local Privilege Escalation Vulnerability

The 14 vulnerabilities below are being released as zero-day vulnerabilities because they remain unpatched.

ZDI-CAN-22238: (0day) VIPRE Advanced Security SBAMSvc Link Following Local Privilege Escalation Vulnerability
ZDI-CAN-22260: (0day) AVG AntiVirus Free AVGSvc Link Following Local Privilege Escalation Vulnerability
ZDI-CAN-22272: (0day) Avast Free Antivirus AvastSvc Link Following Local Privilege Escalation Vulnerability
ZDI-CAN-22803: (0day) AVG AntiVirus Free Link Following Denial-of-Service Vulnerability
ZDI-CAN-22806: (0day) Avast Free Antivirus Link Following Denial-of-Service Vulnerability
ZDI-CAN-22942: (0day) AVG AntiVirus Free icarus Arbitrary File Creation Denial of Service Vulnerability
ZDI-CAN-22960: (0day) AVG AntiVirus Free AVGSvc Link Following Local Privilege Escalation Vulnerability
ZDI-CAN-22963: (0day) Avast Free Antivirus AvastSvc Link Following Local Privilege Escalation Vulnerability
ZDI-CAN-23005: (0day) F-Secure Total Link Following Local Privilege Escalation Vulnerability
ZDI-CAN-23375: (0day) Panda Security Dome Link Following Local Privilege Escalation Vulnerability
ZDI-CAN-23402: (0day) Panda Security Dome Link Following Local Privilege Escalation Vulnerability
ZDI-CAN-23413: (0day) Panda Security Dome Link Following Local Privilege Escalation Vulnerability
ZDI-CAN-23428: (0day) Panda Security Dome VPN DLL Hijacking Local Privilege Escalation Vulnerability
ZDI-CAN-23429: (0day) Panda Security Dome VPN Incorrect Permission Assignment Local Privilege Escalation Vulnerability

Conclusion

As mentioned previously, we fear that there may be several other vendors whose products are currently vulnerable, but because their products are paywalled, we were not able to test them. We hope the techniques and cases presented in this blog series have inspired you to explore and identify vulnerabilities that you can submit to the ZDI program. You can find us on Twitter at @Izobashi and @NZubrisky and the team on Twitter, Mastodon, LinkedIn, or Instagram for the latest in exploit techniques and security patches