Recently I’ve seen a decent number of privilege escalations occurring on Windows due to permission issues and using symlinks. The work from Ryan Hanson from Atredis on the Cylance privilege escalation and Windows Standard Collector privilege escalation really inspired me to research more into this issue and potentially find some myself.
After several weeks of researching the usage of symlinks, hardlinks, and junctions on Windows (mostly provided by James Forshaw at Google’s Project Zero), I felt as if I had a basic understanding of the attack vector used. So, the next question was where do I start looking for my own privilege escalation using symlinks?
The answer to that was rather simple. While reviewing some past findings from another researcher, Codewatch, I came across this PRTG Network Monitor tool and was surprised that the web application was running processes as SYSTEM. So the logical next step was to download the tool and see what I could break!
Upon downloading the software, the first thing I did (since my goal was to find issues where symlinks could be leveraged) was to monitor the services running using Procmon.exe. To my surprise, I found SEVERAL instances where I could use symlinks to gain SYSTEM level privileges! What luck right?
The issue stems from a service named “PRTG Probe Service.” One of the actions taken by this service is to write logs under the notorious C:\ProgramData\ directory.
Side note: it appears that the ProgramData directory gets a lot of vendors in trouble so extra attention should be placed on permissions in that location.
In total, there are four directories written to by the “PRTG Probe Service” as SYSTEM; one of those shown below in Figure 1.
Figure 1: Vulnerable Log Files
The other directories are:
• C:\ProgramData\Paessler\PRTG Network Monitor\Logs (Debug)
• C:\ProgramData\Paessler\PRTG Network Monitor\Logs (Sensors)
• C:\ProgramData\Paessler\PRTG Network Monitor\Logs (System)
• C:\ProgramData\Paessler\PRTG Network Monitor\Logs (Web Server)
The issue isn’t actually the symlink, it is the access rights assigned to those files, as seen in Figure 2. For some odd reason PRTG designed the application to create these log files with absolutely ZERO permissions assigned!
Figure 2: Permissions for log files
Because no rights are assigned to those log files, a low level (non-privileged) user can do the following, which is explained in greater detail in the “Proof of Concept” section:
- Delete all files in “C:\ProgramData\Paessler\PRTG Network Monitor\Logs*” directories.
- Create a symlink using any of the log files and redirecting them to a new directory. Using RPC we can rename the file along the way (this is done as SYSTEM since the service will be creating the file).
The steps above allowed me to redirect one log file to the “C:\Program Files (x86)\PRTG Network Monitor\Notifications\EXE” directory and rename it to exploit.bat. The batch script created a new user and added that user to the Administrators group.
One thing to note: I didn’t need to create the exploit.bat file to gain escalated privileges. I could have created a DLL where one was missing and conduct DLL hijacking or binary planting. I did it this way as I was interested in seeing how the notifications job worked.
The below proof of concept shows one way of exploiting this issue along with a video showing a different log file being leveraged for exploitation.
Proof of Concept:
The first step in the attack is to remove all files from the “C:\ProgramData\Paessler\PRTG Network Monitor\Logs*” directory as a low-level user. In the Figure 3 example below, I used the “C:\ProgramData\Paessler\PRTG Network Monitor\Logs (System)\” directory.
Figure 3: Deleting files from target directory
We then created a symlink from our target directory to a new location as well as using an RPC call to rename the file. In Figure 4 we use the file “PRTG Probe Log (1).log” and moved it to “C:\Program Files (x86)\PRTG Network Monitor\Notifications\EXE\exploit.bat”. This allows files within that directory to be executed from the web application through notifications with SYSTEM privileges. We could have moved this file to a location where the program looked for a DLL which did not exist, and performed DLL hijacking.
Figure 4: Showing user rights and creation of symlin
After the symlink was created, we restarted the service. We restarted the service as admin just for ease of testing, however, in the directory “C:\ProgramData\Paessler\PRTG Network Monitor\Logs (Web Server)” we can create a symlink with that log file and then browse to the web page. The program then attempted to write to the web server log file which is our symlink, as seen in Figure 5.
Figure 5: Showing the usage of Web Server log instead of restarting service
In Figure 6, we show that the file exploit.bat did not exist prior to exploitation and that files within that directory are not editable by low-level users.
Figure 6: Contents of EXE directory and rights of files within
After restarting the service we see that the symlink is followed by the service, and the file exploit.bat is created and the rights for that file make it so any user on the system can edit it, as seen in Figure 7.
Figure 7: Proof exploit.bat was created and the rights for that file
As a low level-user we added malicious code to exploit.bat (as seen in Figure 8) that upon execution, adds a local administrator account.
Figure 8: Code within exploit.bat
Figure 9 shows the accounts that exist on the victim machine prior to exploitation.
Figure 9: Accounts that exist prior to exploit
Finally, due to my curiosity, we created a notification in the Web-GUI (as seen in Figure 10) and used the “execute notification” feature to force the execution of the exploit.bat program.
Figure 10: Creation of the notification job
Upon execution, we can see in Figure 11 that our wonderful user “pwn” was created and added as a local administrator!
Figure 11: Pwnage!
We have also added a script to exploit this issue on our GitHub page.
Concerned about the successful privilege escalation, I disclosed the issue in July to the vendor, Paessler, but unfortunately, they did not consider it a security issue (see Figure 12) and to my knowledge, have not informed their clients of the risk. I have validated that a patch was created for this issue and released. However, I am not sure when that patch was released. I am now releasing this information in the public interest, so end-users can take preventative actions.
Figure 12: Email from PRTG
2018-07-08 – Vendor Disclosure.
2018-07-09 – Vendor Responded Claiming No Security Issue.
2018-07-09 – Responded back to vendor with further details and public info on why it is an issue. Vendor didn’t respond.
2018-07-13 – Emailed vendor to check status. Vendor didn’t respond.
2018-09-20 – Confirmed vendor fixed security issue. Vendor still hasn’t responded.
2018-10-03 – Public Release.
Discovered by Quentin (Paragonsec) Rhoads-Herrera of Critical Start – Section 8.