Exploiting GlobalProtect for Privilege Escalation, Part One: Windows

picture of hand pointing to broken padlock

The CrowdStrike® Intelligence Advanced Research Team discovered two distinct vulnerabilities in the Windows, Linux and macOS versions of the Palo Alto Networks GlobalProtect VPN client (CVE-2019-17435, CVE-2019-17436). The vulnerabilities allowed unprivileged users to reliably escalate to SYSTEM or root on machines where GlobalProtect software is used. Fixed versions were released on October 15, 2019, by Palo Alto Networks. We would like to thank Palo Alto Networks for handling and addressing the reported issues in a timely and professional manner.

This is the first of a two-part series of blogs covering the exploitation of GlobalProtect for Windows. The second part will cover the exploitation of Linux and macOS clients.

Quick Facts

Affected Vendor: Palo Alto Networks
Affected Software: GlobalProtect for Windows (on Windows 10 LTSC 1809 Build 17763.107)
Affected Version: 5.0.3 (and earlier), 4.1.12 (and earlier)
Fixed Version: 5.0.4, 4.1.13
Vulnerability: Race Condition / TOCTTOU
Estimated Risk: High (Local Privilege Escalation to SYSTEM)
Identifiers: CVE-2019-17435 / GPC-8977 / PAN-SA-2019-0036
Vendor Reference: https://security.paloaltonetworks.com/CVE-2019-17435

The CVE-2019-17435 Vulnerability

The Windows GlobalProtect VPN client consists of the following two components:

  • PanGPS.exe: PanGPS is started once during boot time. It is responsible for negotiating VPN connections, configuring network devices and adjusting routes accordingly, as well as installing software updates. To fulfill these tasks, it runs with SYSTEM privileges. PanGPS listens for incoming TCP connections on 127.0.0.1:4767.
  • PanGPA.exe: PanGPA is automatically started once per log-in session and runs with the privileges of the logged-in user. PanGPA is responsible for displaying the graphical user interface (GUI), informing the user about status changes, and downloading software updates, among other things. PanGPA delegates any privileged actions to PanGPS. Inter-process communication (IPC) with PanGPS is implemented via a TCP connection to 127.0.0.1:4767.

GlobalProtect IPC

It was found that all messages that are exchanged between PanGPA and PanGPS are encrypted using AES-256 in cipher block chaining (CBC) mode. The initialization vector (IV) is fixed and consists of 16 null bytes. The AES key can be derived from the machine’s security identifier (SID) as follows:

AES_KEY = MD5(SID + MD5(“pannetwork”)) + MD5(SID + MD5(“pannetwork”))

Each encrypted message is prefixed with a 16-byte header that announces the length of the body as ASCII-encoded decimals, padded with null bytes. The beginning of an encrypted example message is shown below:

screenshot of encrypted ASCII-encoded message

Further investigation showed that the encrypted messages contain XML documents. XML documents are used for both — PanGPA requesting actions from PanGPS and PanGPS reporting back status information to PanGPA. One of the most frequently observed requests is the user_credential request:

screenshot of user_credential request

It is used to communicate the username, password and the hostname of the VPN portal from PanGPA to PanGPS, which then tries to establish a VPN connection and periodically reports back status.

Software Upgrades

During regular usage, it was observed that the GlobalProtect VPN client updates itself automatically without requiring any user interaction. That update process was found to be divided into two parts. First, PanGPA downloads a potential update and stores it in the current user’s %Temp% directory as an .MSI file. Afterward, PanGPA sends a software upgrade request to the privileged PanGPS process. That request contains the absolute path to that MSI file:

<request>
  <type>software-upgrade</type>
  <command-line>C:\Users\USER\AppData\Local\Temp\_tempXXXX.msi</command-line>
</request>

PanGPS then verifies the signature of the file and, if the verification succeeds, copies it to C:\Windows\Temp\globalprotect.msi. If the destination file does not exist, the owner of the newly created file will be SYSTEM; otherwise, the existing file is overwritten and ownership will be preserved. After copying, the source file is deleted, and the signature of the copied file is verified again. If the verification succeeds, PanGPS writes a batch file that orchestrates the actual update process to C:\Program Files\Palo Alto Networks\GlobalProtect\update_tmp.bat. The batch file instructs Windows’s Service Control Manager to stop the PanGPS service. It then enters a loop with a three-second delay to wait for PanGPS to enter the “stopped” state. The three-second delay is implemented using timeout.exe (highlighted in red), which is invoked at least once:

echo off
set /a _count=0
"C:\Windows\system32\sc.exe" stop pangps > null
:loop
if %_count% GTR 300 goto exittimeout
"C:\Windows\system32\timeout.exe" /t 3 /nobreak > null
set /a _count=_count + 3
"C:\Windows\system32\sc.exe" query pangps | find "STOPPED"
if errorlevel 1 goto loop
cd C:\Program Files\Palo Alto Networks\GlobalProtect
"C:\Windows\system32\msiexec.exe" /x "{D7FDA55F-21EC-43A9-A917-CCBABE5A708A}" /qn /norestart
    KEEPREGISTRIES="YES" /l+* "C:\Program Files\Palo Alto Networks\GlobalProtect\PanGPMsi.log"
"C:\Windows\system32\msiexec.exe" /norestart /qn /i "C:\Windows\TEMP\globalprotect.msi"
    TARGETDIR="C:\Program Files\Palo Alto Networks\GlobalProtect"  BENICE="yes" /l+*
    "C:\Program Files\Palo Alto Networks\GlobalProtect\PanGPMsi.log"
goto normalexit
:exittimeout
echo %date% %time% - PanGPS service cannot be stopped. time out 300. >> "C:\Program Files\Palo
    Alto Networks\GlobalProtect\PanGPS.log"
exit 1
:normalexit

After the loop, the old GlobalProtect VPN client is uninstalled (highlighted in green), and the new version is installed from the file C:\Windows\Temp\globalprotect.msi (highlighted in blue).

This behavior allows for a three-second window during which the copied and already-verified MSI installer at C:\Windows\Temp\globalprotect.msi can be replaced with a malicious payload. However, the following prerequisites must be met so that unprivileged users can successfully exploit this vulnerability to achieve local privilege escalation to SYSTEM:

  • The file globalprotect.msi in the global temporary directory cannot be removed or replaced by the unprivileged user unless it is owned by them. GlobalProtect installers that have been left in the temporary directory after previous updates usually belong to SYSTEM. In such a situation, either the ownership must be changed first, or alternatively, the installer must be deleted.
  • In order to exploit this vulnerability without having to wait for a real update to happen, a way to initiate a fake update must be found. Crafting a fake software upgrade message, encrypting it and sending it to the PanGPS TCP socket should allow exactly this, however.
  • The PanGPS daemon only accepts a single TCP connection on its listening socket, and that connection must originate from a process created from a PE image in C:\Program Files\Palo Alto Networks\GlobalProtect.

There are ways to fulfil all of these preconditions and reliably trigger an update process that executes an attacker-supplied globalprotect.msi file with SYSTEM privileges.

The Exploit

As outlined previously, the exploit needs to be able to send an upgrade request to PanGPS, but also to replace a valid upgrade file with a malicious one.

Triggering the Upgrade

For the exploit to be useful in a real-world scenario, a primitive for manually triggering the update process is required. This should be possible through the TCP-based communication protocol between PanGPA and PanGPS. However, the Windows version of PanGPS does not allow multiple concurrent connections to its listening socket, and the single permitted connection has usually already been established by the PanGPA process. Additionally, the Windows version of PanGPS conducts a check on every incoming connection to ensure that the PE image of the connecting process points to an executable located below C:\Program Files\Palo Alto Networks\GlobalProtect. Unprivileged users usually are not allowed to write to directories below C:\Program Files.

Both the PE image check and the connection limit can be bypassed by injecting a DLL into PanGPA. The update process can then be triggered as follows: 

  1. First, an injector helper executable computes the machine-based AES encryption key, encrypts a fake software upgrade request message and writes it to disk.
  2. Next, the injector requests the current IPv4 TCP connection table using  GetExtendedTcpTable() and searches the result set for a PanGPA process that has already established a connection to 127.0.0.1:4767. If found, the corresponding process ID is opened via OpenProcess() using the desired access PROCESS_ALL_ACCESS. Afterward, a prepared DLL is injected via CreateRemoteThread().
  3. The injected DLL then enumerates all socket handles that belong to the process. When a socket handle connected to 127.0.0.1:4767 is found, the previously encrypted packet is read from disk and sent to that socket, which then triggers the update process.

Replacing the Upgrade File

The vulnerability can only be exploited successfully if the MSI file path C:\Windows\Temp\globalprotect.msi is writable by the unprivileged user, so that it can replace that file with a malicious payload during the update process. However, if there was previously a legitimate software update, that file may already exist and belong to the SYSTEM user, which would prevent regular, unprivileged users from deleting or replacing the file. In such a case, that file has to be removed first. This can be achieved through some side effects of the update process:

File Deletion

After starting the installation of a PAN-signed MSI file, the source MSI file gets deleted by PanGPS after copying it to C:\Windows\Temp\globalprotect.msi. Therefore, if a software upgrade request with that path as the source is issued, PanGPS verifies the signature of the source, copies the source file onto itself and then deletes it. The second verification of the signature will then fail, and no real upgrade will be performed.

For PanGPS to perform these operations, the source file (i.e., the file globalprotect.msi that must be deleted) has to be digitally signed by PAN, which might not always be the case in a real-world scenario. To improve the reliability of the exploit, the file deletion can therefore be prepended with another software upgrade request with a known good, PAN-signed MSI file as the source. That “upgrade” should normally finish successfully and leave a correctly signed MSI file in C:\Windows\Temp\globalprotect.msi, which can then be deleted by the previously documented technique to ensure write access for the unprivileged user.

File Replacement

After performing these steps, the system will be in a state where there is no globalprotect.msi file present in C:\Windows\Temp, and an unprivileged user can simply claim ownership by touching it. Next, the software update process can be initiated with a PAN-signed MSI file as the source. After PanGPS has verified the authenticity of C:\Windows\Temp\globalprotect.msi, it will execute the batch file. The timeout.exe process will be invoked, and the corresponding process list entry can be used as an indicator for the exploit that it is the right time to replace the globalprotect.msi file with an attacker-controlled version. After the timeout loop finishes, the old GlobalProtect installation is removed, and the now attacker-controlled MSI file is installed. 

The Payload

To elevate privileges to SYSTEM, our exploit uses an MSI file that spawns a SYSTEM shell. It also triggers a re-installation of the real GlobalProtect client to maintain the integrity of the GlobalProtect software installation.

screenshot of code with PAN GP logo

Conclusion

In this blog, we showed how a combination of several seemingly minor issues in GlobalProtect for Windows can be exploited to successfully elevate privileges on Windows. To recap:

  • The GlobalProtect Agent consists of two components, PanGPS and PanGPA, of which PanGPS runs with elevated privileges so that it can perform privileged operations, such as upgrading the agent software.
  • To trigger a software upgrade, an unprivileged user must communicate with PanGPS over a local TCP connection. PanGPS tries to ensure that only PanGPA can establish such a connection, but this check can be bypassed by injecting code into PanGPA.
  • Once an upgrade has been triggered, an unprivileged user can race against the update process and replace a benign, signed MSI file with a malicious payload, which is then executed with elevated privileges.
  • This file replacement can only succeed if the user is able to manipulate the file. This is not always a given, but additional flaws in PanGPS allow unprivileged users to remove any conflicting files and take control before starting the actual privilege escalation exploit.

Stay tuned for Part Two, where we will discuss another vulnerability in GlobalProtect for Linux and macOS, which allows escalation of privileges on these platforms as well.

Additional Resources

Related Content