War Stories: Popping PRTG
Sometimes a seemingly patched version of a software product will remain vulnerable to an older exploit which is not expected to work. This is because the problematic code may later be inadvertently reintroduced to the product code base. In this article, I will cover such a case discovered with PRTG.
Intro to PRTG
PRTG Network Monitor is a popular solution for remotely monitoring various kinds of assets on an enterprise network including endpoints, servers, network devices, and peripherals. As the server running a network monitoring application would typically need expansive network-level access across the organization as well as credentials to access each system monitored, this naturally makes these sorts of solutions a prime target for penetration testers and real-world threat actors.
The Original Vulnerability
The vulnerability tracked as CVE-2018-9276 was originally uncovered by a researcher named Josh Berry. The attack vector for this vulnerability involved a feature called Notification Templates and the configuration option called “Execute a Program”, which allows a user to specify a binary or script to run either on-demand or upon activation of a given sensor state. An important restriction to note is that you cannot specify an arbitrary file to be executed, rather the file must be located within the PRTG installation subfolder “\notifications\exe”, which only includes a couple demo files on a default installation.

Interestingly however, you are able to specify an arbitrary set of parameters to pass to the executed file. This is where all the magic happens! The PRTG application did not perform proper input sanitization of all characters, which is what ultimately allowed an attacker to exploit the application and achieve OS command injection.

Originally, the MITRE documentation for this CVE stated that the vulnerability only applied to releases of PRTG prior to v18.2.39. In this case, I was working with more recent version of PRTG released a couple years after that cutoff. Nonetheless, I was able to confirm that this vulnerability was still present and exploitable in contrast to what the CVE details or a vulnerability scanner report would have you believe.
Return of the Exploit
Let’s start out by logging in to the “patched” instance of PRTG, in this case v20.4.63, and start creating the malicious Notification Template. Luckily for me, the application login credentials were still set to defaults. It’s nice when things work out! This exploit does require authentication – sorry to disappoint anyone hoping to see some RCE.

First, I am going to create a new Notification Template and simply add a slew of special characters to the “Parameters” field which might be useful when crafting a PowerShell payload. Based on what works and what doesn’t, I can ensure the payload I craft is limited to the characters which are abusable.

After saving this Notification Template, checking the configuration file within the PRTG ProgramData directory reveals that most of these special characters are not being properly encoded by PRTG. This is a strong indicator that I may be able to execute some arbitrary code within the PowerShell script parameters.

To test the theory, I created a simple payload to create a file on disk. Per the results above, each of the special characters used in this payload should work as expected.

The results were successful! Checking the PRTG server, I saw that the test file was created successfully, thus confirming the vulnerability is still present even in this seemingly patched version of PRTG.

Further Weaponization
Now that we have confirmed this vulnerability is still alive and well, I will demonstrate a fun way to leverage this exploit into a makeshift web shell which will fetch code from an attacker-controlled server, and execute it locally on the PRTG server, and send the results back to the attacker. First, I will make the below adjustments to the malicious Notification Template. Note that I am still only using characters in my payload which are not properly sanitized by PRTG.

Next, I will need to create the script file to host on my attacker machine which will be fetched by the PRTG server when the Notification Template is executed. For now, I will just add some code to do basic local file system recon so see if there is anything interesting to explore further. Note that at this point we no longer need to worry about which characters are sanitized by PRTG as we did when crafting the payload string saved directly within the “Parameters” field.

Now I can just start up an HTTP server on my attacker machine to host the script file and then manually trigger the Notification Template. As you can see from the log below, the script file was successfully fetched by PRTG, executed, and our results were delivered back to us via HTTP as expected. Furthermore, we can see that we did identify one file which is, well, interesting.

I can simply adjust the script file hosted on my attacker machine to exfiltrate this file over HTTP. Below is what the updated code looks like.

Depending on the HTTP server you are using to host the script file, you may need to make some adjustments ensure the new request methods and the request data are properly handled. In my case, I was using a Python module to serve the files and needed to create a slightly more customized implementation which would both log the GET requests as well as save files to disk which were uploaded via a PUT request. After running this new Python script and re-executing the PRTG Notification Template, the new PowerShell script was successfully fetched and the “interesting” file was successfully exfiltrated.

Below you can see the file was transferred intact. At this point, I now had a successful data exfiltration channel which I could leverage to further pillage the server. Additionally, because the PowerShell script was being fetched at runtime from an attacker system by PRTG, our PowerShell payload was no longer restricted to characters not properly sanitized by PRTG.

In my case, the PRTG service was running as SYSTEM (and thus our PowerShell payloads were executing in the SYSTEM context as well). In that case, you may opt to simply create a new local administrator account and connect to the PRTG server using trusted channels such as RDP, SMB, WinRM, etc.
Disclosure
I disclosed my findings to the Paessler security team on 9/19/2022, which they were able to confirm on 10/14/2022 as a reintroduction of the original CVE-2018-9276 OS command injection vulnerability to the PRTG code.

Per their internal analysis, additional affected versions of the software include any releases after v19.3.52 and before v21.2.68. The patch for this vulnerability is now noted in the v21.2.68 release notes on the PRTG website.