Protect Against Russia-Ukraine Cyber Activity

Why Are My Junctions Not Followed? Exploring Windows Redirection Trust Mitigation

Conceptual illustration showing malicious files

This post is also available in: 日本語 (Japanese)

Executive Summary

In recent years, one of the most common classes of elevation-of-privilege vulnerabilities is file system redirection attacks. This class abuses the fact that a privileged component, such as a Windows service, operates on files or directories that are writable by unprivileged users. By using different types of file system links, such as hard links or junctions, attackers can trick the privileged component into operating on files it didn’t intend to. The end goal for such attacks is usually to write an attacker-supplied executable (such as a DLL or a script) to disk, and to get it executed with system permissions.

Some examples for such exploits can be found in my BlueHat IL 2020 talk, CVE-2020-0787 Metasploit module and many more.

This piece explains junctions and how threat actors use them in file system redirection attacks, then explores a developing mitigation.

Palo Alto Networks customers receive protections from Cortex XDR against exploits for different types of file system redirection attacks.

Table of Contents

What Are Junctions?
Redirection Trust Mitigation
How Redirection Trust Works
Is the Mitigation Enabled?
Conclusion

What Are Junctions?

Junctions are a feature of the NT file system (NTFS) that make it possible to link one directory into another. They are used by default, linking some directories such as C:\Documents and Settings.

The screenshot shows an example of how a junction is used in NTFS to link one directory into another – in this case, Documents and Settings.
Figure 1. Example of junction in use.

In 2019, Microsoft introduced a mitigation that requires the creator of hard links to have write access to those links’ targets. Since then, junctions became the way to go for attackers when exploiting file system redirection attacks.

A common vulnerable pattern is usually as follows:

  • A privileged service exposes functionality that can be triggered through some interprocess communication (IPC) mechanism, such as remote procedure call (RPC). That functionality can be triggered by users running at lower privilege levels.
  • That functionality operates on a file (e.g. writing data into that file) that is located under a globally writable directory. The operation is done without impersonation, meaning it occurs with the permissions of that system service.

To exploit such bugs, the attacker first creates a junction between that directory and their target, which is usually C:\Windows or one of its subdirectories. Next, the attacker triggers the RPC call, which follows the junction to overwrite a system DLL file. Finally, that malicious DLL is loaded by some service, and the attacker’s supplied code gets executed with system permissions.

The flow chart shows how a file system redirection attack works. Beginning from the execution by the user of an attacker's file, an RPC (WriteLogFile("update.dll", buffer) leads to system execution, which leads to the creation of a file written to logs, which then follows a junction to overwrite a system DLL file.
Figure 2. Example of a file system redirection attack.

Redirection Trust Mitigation

Microsoft announced they are going to ship a mitigation for this bug class in David Weston’s talk at BlueHat IL 2020 – “Keeping Windows Secure.” However, this mitigation only appeared on recent Windows 10 builds, so I decided to reverse engineer it and explore how it works.

The presentation slide reads, "Path Redirection Mitigations - Mitigations coming in a future release. Hardlink mitigation - will now require write permission to link destination before creation. Already available in Windows Insider Preview (and bounty eligible). Junction mitigation - Newly created junctions gain a 'mark of the Medium IL,' services running highly privileged will not follow "marked" junctions. SYSTEM%TEMP% change - Today, SYSTEM's %TEMP% value is \Windows\Temp, which is world writable, GetTempPath will return a new, properly ACL'd path for SYSTEM."
Figure 3. Screenshot from a presentation called “Keeping Windows Secure,” given at BlueHat IL 2020.

How Redirection Trust Works

The mitigation is fairly simple and follows the guidelines presented at Microsoft’s BlueHat talk. Its goal is to mark junctions created by unprivileged, medium-integrity actors, and prevent privileged processes from following them.

Every time a junction is created, ntfs.sys calls nt!IoComputeRedirectionTrustLevel to compute the caller’s trust level. The level is determined based on the caller’s token – either the impersonation token (if present) or the primary token. Later, it sets that value into that junction file control block’s standard information.

The screenshot shows an example of how, when a junction is created, ntfs.sys calls nt!IoComputeRedirectionTrustLevel to compute the caller's trust level.
Figure 4. ntoskrnl.exe 10.0.19041[.]1645
Currently, there are only two trust levels:

  • Level 1 – Indicating the junction was created by a medium-integrity actor.
  • Level 2 – Indicating the junction was created by a privileged actor (administrator, system or kernel).

To complete the mitigation, the trust level is verified before following junctions. This is done only if the mitigation is enabled, which is controlled by a new process mitigation policy – ProcessRedirectionTrustPolicy. That policy has two modes: audit or enforce.

The screenshot shows the two modes available in the ProcessRedirectionTrustPolicy: audit or enforce.
Figure 5. New struct added to winnt.h header.

When SetProcessMitigationPolicy is called with the relevant arguments, it ends up calling nt!PspSetRedirectionTrustPolicy. This enables the mitigation on the process’s primary token.

SetProcessMitigationPolicy calls nt!PspSteRedirectionTrustPolicy as shown, enabling the junction mitigation.
Figure 6. Enabling the mitigation.

Finally, when ntfs.sys goes through a junction redirection, it verifies it against the caller’s token using nt!IoCheckRedirectionTrustLevel. This means that when a privileged service operates with its own system privileges, untrusted junctions are not followed. Failed redirects end up with error 0xc00004be – “The path cannot be traversed because it contains an untrusted mount point.”

Is the Mitigation Enabled?

After reverse engineering the mitigation, I wanted to check whether it is enabled on the current Windows build, and in which mode. I created a sample app that queries the state of all running processes (using GetProcessMitigationPolicy), and found out that the mitigation is currently only enabled in audit mode for several services. Hopefully, in the near future, Microsoft will enable it in enforce mode.

The screenshot shows the details of how the mitigation is enabled on the current Windows build, and in which mode - the result of a sample app that queries the state of all running processes. The mitigation is currently only enabled in audit mode in several services.
Figure 7. Redirection trust policy enablement.

Conclusion

In the last few years, Microsoft has pushed numerous mitigations to address file system redirection attacks. It is important to explore them and assess their effectiveness, trying to identify gaps and conditions where bugs can still be exploitable.

Palo Alto Networks Cortex XDR already has many protections in place to prevent exploits for different types of file system redirection attacks, and was proven to prevent such attacks in the wild.