In our last Assume Breach engagement, the client gave us a domain-joined computer and a VPN access telling it was the only option to access the internal domain. Other computers would be able to access to some resources using specific protocols but nothing more. This behavior can be challenging as the domain workstation is protected by several security solutions and using offensive tools from it could be risky. Therefore, it was mandatory to remove this restriction to be able to ease the assessment completion.
A great part of pentester’s job is to bypass the restrictions set up by security tools, this VPN being the perfect exercise for a pentester.
This article is not meant to show a fancy 0day, but to expose the thinking pentesters use when dealing with a black box security tool.
The exploit path presented in this article takes for granted that:
- The attacker already has access to a valid set of user’s credentials
- The attacker has managed to get a limited access to a workstation for a limited period of time
Depending on the VPN configuration, this last prerequisite can be optional.
Discovering the environment
With access to the computer, the first thing we tried was to extract the VPN client binary and use it on the attack computer.
The VPN tested was the Palo Alto GlobalProtect solution, and the VPN client can be easily downloaded on Internet. Once the client is installed on the computer, a connection is initialized. The VPN initialized a connection with the VPN portal exposed on Internet and a Microsoft authentication is triggered:
The domain credentials worked, and the VPN tunnel was successfully mounted. However, all connections were filtered, and it was not possible to even reach the domain controller as it had initially been hinted by the clients.
Global Protect Host Information Profile
Global Protect VPN, as several other business VPN, allows administrators to define a host information policy.
This host information policy allows the server to verify that the user computer is compliant with the company’s security policy before allowing access to the company’s internal network.
This type of access control can be tuned, and administrators can simply reject any non-compliant devices as well as limit the protocols allowed for the device. For example, a computer that does not comply with the company’s security policy could be restricted to only access a web application exposed in the internal network but not access any other internal resource.
The VPN client then collects host information once the user has successfully signed in on the VPN gateway and an update is sent on a regular basis to ensure the computer is still compliant with the company’s security policy.
Global Protect can collect the following information:
- General: Information about the host itself such as hostname, logon domain, OS etc…
- Patch Management: Information about any patch management software installed on the machine
- Firewall: Information about the firewall software deployed and its status
- Anti-malware: Information about the anti-malware/anti-spyware software deployed and its status
- Disk backup: Information on whether disk backup software is installed and enabled
- Disk encryption: Information on whether disk encryption software is installed as well as which disks are encrypted and what encryption method is used
- Data loss prevention: Information on whether a DLP software is installed and enabled
- Certificate check: Information on the certificates deployed on the computer
- Custom checks: Information on registry keys, user-space application etc…
All the information collected can be retrieved on the client GUI:
Thus, if you have access to a machine that can legitimately connect to the VPN, it is possible to retrieve a sample of an allowed host configuration.
Hijack the profile
The host profile (that will be named HIP report from now) is thus generated by the host and sent to the gateway.
The first thick client pentesting rule is: If you generate it, you can tamper it. Thus, instead of modifying the host configuration – which can be painful and require the knowledge of how Global Protect retrieves this information – it should be possible to tamper the HIP report sent to the VPN gateway.
Go in easy with a proxy
A quick and dirty way to tamper the HIP report is to intercept the requests and modify the report sent to the VPN.
The VPN client communicates with the VPN gateway using the HTTPS protocol. Therefore, it is only possible to intercept the traffic and modify the content sent if the VPN does not securely check the VPN gateway certificate.
In order to intercept the traffic, we need to:
- Configure Burp as a transparent proxy and configure the redirection in Burp to forward the request to the VPN gateway
- Add the Burp certificate to the Windows certificate store
- Specify the Burp address as a VPN gateway in GlobalProtect
From now, when a VPN connection is performed, Burp will be able to intercept the traffic. However, with this technique, it was not possible to login:
It was not possible to understand what raised this error, maybe due to some certificate pinning or other security solutions: the easy solution did not yield any positive result.
Understand the logic
The Burp solution out of the way, it appeared mandatory to understand how the VPN works. The first thing done was to monitor the VPN processes during the connection to identify the VPN executables to target and what their role in the profile generation is.
ProcessHacker showed several processes implied in the profile generation:
- PanGps.exe: executed as Administrator
Procmon gave a lot of information and showed that the PanGpHip.exe and PanGpHipMp.exe binaries were launched by the PanGps.exe binary:
Finally, exploring the Global Protect installation folder showed several detailed log files, which have been really helpful during the reverse and debugging process:
Additionally, during the VPN connection an XML file is created and contains the full HIP Report that has been generated during the connection process. However, the creation of this file was not reported in Procmon.
In order to ease the exploitation, the report generated on the domain joined machine was retrieved. Depending on the VPN configuration, part or totality of this report can be guessed but it will complexify the exploitation scenario.
The idea was to understand the purpose of each executable and how they were communicating with each other.
Killing the PanGPA.exe process showed that it corresponded to the user GUI. Nothing really interesting appeared in this executable.
The PanGpHip.exe binary was the first to be reversed as its name gave hints on its features.
Ghidra was used to analyze the .rdata section to look at the hardcoded strings. Several strings could help to understand the goal of the binary.
For example, the following strings shows that this executable is used to retrieve the host configuration:
Likewise, the following string shows that the process write the HIP report:
Looking at the references for these strings shows, they are part of a C++ object:
Indeed, the vftable is a table containing all virtual functions from a C++ object. It can be guessed that all the functions contained in this vftable are used to retrieve some configuration information on the host.
After analyzing each virtual method, it is possible to start understanding how the object works:
From now on, it is a known fact that this binary is used to generate the HIP Report. However, the string pan_gp_hrpt.xml, which is the filename of the file containing the Hip Report and written on the disk is not present in the binary. Therefore, there is a high probability that the XML report it is not written on the disk by this executable.
The first idea was the PanGpHip.exe binary generates the report and forwards it to the PanGPS.exe executable that will write it on the disk as it is the only one executed with Administrator privileges, so with enough privileges to write in the Program Files directory.
The issue was to ensure that the report generated by the binary was the XML report is actually sent to the VPN gateway and is not an aggregation of binary data that could not be easily modified.
In order to avoid reversing several functions, a dynamic approach was preferable for this task. The binary is not statistically compiled, and several Win32 Api are used. Using ApiMonitor it is possible to spy on the Win32 API calls performed by the binary.
ApiMonitor was configured to intercept every call performed to the WriteFile Win32 API. At the end of the PanGpHip.exe execution, the full XML report was written in a file:
However, it was not possible at this moment to find the file where this content was written on. This point was set aside for a moment to progress on the reversing of the parent binary.
We saw earlier through Procmon that PanGPS.exe launches the PanGpHip.exe binary. Through Ghidra, it is possible to search how it is launched. This information is interesting because if a communication is performed among binaries, some PIPE or sockets should be used to allow the interprocess communication, with a high probability that they are created by the parent process.
The following code is used to run the PanGpHip.exe process:
The process creation is performed using the Win32API CreateProcess. The StartupInfo object is created with the following code:
The stdin, stdout and stderr file are overwritten with custom PIPE created by PanGPS.exe as it is shown in the following figure:
Thus, through these PIPE objects the PanGpHip.exe process will be able to communicate the Hip Report generated.
Using API Monitor this assumption has been verified. The tool was configured to intercept the CreatePipe, ReadFile and WriteFile Win32 API calls. First, it was verified that the PanGPS.exe binary really read the HIP Report:
This API call shows that the XML report is, at a moment, forwarded from PanGpHip.exe to PanGPS.exe. Looking at the parameters used in the ReadFile, the PanGPS.exe binary read the data from the 0x5A0 handle.
Looking at the CreatePipe calls, this handle represents the PIPE used as the stdout for the PanGpHip.exe process:
Likewise, if the WriteFile API call performed by the PanGpHip.exe process is analyzed, the handle that is used will be the one related to the stdout PIPE created by the PanGPS.exe process.
The following figure summarizes the interactions between the different components:
- PanGPS: the high integrity process that communicates with the VPN gateway
- PanGpHip: the process spawned by PanGPS that generate the compliance report
- PanGpHipMip: the process spawned by PanGPS that check for known vulnerabilities on the different host programs
Tamper the profile
The previous figure highlighted that hijacking PanGpHip to write a tampered compliance report on its stdout should be sufficient:
A simple C code was written:
Then the PanGpHip.exe file was replaced by this program and a VPN connection was attempted. However, looking at API Monitor, the PanGPS.exe process never retrieved the HIP Report. Actually, the thread used to launch and parse the PanGpHip.exe process was in an idle state (this can be seen in APIMonitor cause the calls performed by each thread were highlighted in a unique color).
Looking in the code of PanGPS.exe, the following wait condition can be seen:
The WaitForMultipleObject condition stalls the PanGPS.exe program as long as the child process does not raise a given event.
It was possible to dynamically retrieve the event definition using APIMonitor again, analyze the parameters used with WaitForMultipleObject and linking the ID with the related CreateEvent parameters.
Looking at the code, the binary creates a specific event using the CreateEvent Win32 API. APIMonitor confirmed that this event is in the list of the waited event.
Another C code, taking this event into account, was written:
Once again, the program was compiled, and used to replace the PanGpHip.exe file. However, even with this modification, the PanGPS binary did not receive the full report.
Using, API Monitor, it was noted that the printf did not use the WriteFile Win32API at all. At first, we thought that under the hood, printf would call the WriteFile API as it just writes data into a PIPE but that was a wrong assumption.
The program is once again modified to use the WriteFile API:
Even with this modification, it was not possible to retrieve the report in the PanGPS.exe binary. Our last option was to reverse, again, the PanGpHip.exe binary to understand how it writes the data in the PIPE.
In fact, the process does not directly write the report in the PIPE, it first writes 10 bytes that represent the size of the report, and then, the full report. This behavior is quite expected as the PanGps.exe process read the full report in one call and, thus, must know the full size of the report to be able to use the ReadFile Win32Api.
Thus, the exploit binary must:
- Compute the report final size
- Format the size on a 10-byte string
- Write this size on the communication PIPE handled by stdout
- Notify the PanGPS.exe process using the HipReportReadyInOtherProcess event
- Write the report on the communication PIPE handled by stdout
- Notify the PanGPS.exe process using the HipReportReadyInOtherProcess event
Finally, the script was modified as follows:
Once the VPN is launched, the modified script is executed, and the tampered profile is sent to the VPN gateway instead of the profile that would be generated by the initial PanGpHip.exe binary.
As the profile sent matched a compliant profile expected by the VPN gateway, the rogue computer was granted access to the internal network without restrictions.
VPN clients and appliances are interesting as they allow remote workers to access the internal network and emulate an in-office experience. However, they also expand the attack surface as an attacker could use them to remotely access the internal network.
In order to mitigate these risks, VPN companies set up some verification rules to avoid unknown devices to access the internal network. These rules often take place as compliance checks that cannot be easily tampered with.
However, because the compliance report is generated directly by the host, an attacker can simply hijack the part of the program that sends the report to the VPN Gateway and injects its own tampered report. Thus, this compliance checks must not be taken as a proof that the connecting computer belongs to the organization.
An “easy” way to prevent these kinds of attacks is to authenticate the user AND the computer accessing to the VPN. This can be done through the use of a machine certificate verification with an asymmetric authentication process.
An 802.1X-like authentication protocol using certificates could be a viable solution for VPN access as this authentication mechanism authenticates the computer, giving a proof that the connecting computer really belongs to the organization.
In this case, even if the attacker can tamper with the compliance checks performed, he will not be able to pass the computer authentication validation and won’t be able to access to the internal network.
However, these solutions can still be bypassed with computer certificate extraction or vulnerability related to 802.1X authentication, but these attacks need Administrators privileges on the computer and/or a physical access to the machine: if an attacker already has Administrators rights or physical access to one of your Domain Workstation, there are way more serious troubles ahead. Additional protections can also be set in place to further harden the access to the certificate, such as storing them on a Virtual Smartcard hosted on the TPM chip.
In a nutshell, if the compliance checks have been set up to avoid users connecting personal devices with a degraded level of security to the VPN, it can do the job.
However, if they have been set up as a network access control mechanism to avoid attackers with valid credentials and host configuration to access to the internal network using their attack machine, they are not sufficient.