Talos Vulnerability Report

TALOS-2019-0924

WAGO PFC100/200 Web-Based Management (WBM) Authentication Timing Information Disclosure Vulnerability

March 9, 2020
CVE Number

CVE-2019-5135

Summary

An exploitable timing discrepancy vulnerability exists in the authentication functionality of the Web-Based Management (WBM) web application on WAGO PFC100/200 controllers. The WBM application makes use of the PHP crypt() function which can be exploited to disclose hashed user credentials.

Tested Versions

WAGO PFC200 Firmware version 03.00.39(12) WAGO PFC200 Firmware version 03.01.07(13) WAGO PFC100 Firmware version 03.00.39(12)

Based on inspection of various firmware versions, this vulnerability appears to impact all versions from the current and going back to at least 10 and likely earlier.

Product URLs

https://www.wago.com/us/pfc200 https://www.wago.com/us/pfc100

CVSSv3 Score

5.3 - CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N

CWE

CWE-208: Information Exposure Through Timing Discrepancy

Details

The WAGO PFC100 and PFC200 devices are programmable automation controllers that boast high cybersecurity standards by including VPN, SSL and firewall software. WAGO controllers are used in many industries including automotive, rail, power engineering, manufacturing, and building management.

An exploitable timing discrepancy vulnerability exists in the authentication functionality of the Web-Based Management (WBM) web application on WAGO PFC100/200 controllers. The WBM application makes use of the PHP crypt() function which can be exploited to disclose hashed credentials. An attacker can make a series of unauthenticated requests to exploit this vulnerability.

The vulnerability exists in the PasswordCorrect() function within the login.php file. User input is passed to the PHP crypt() function to generate a password hash to be used in comparison with the hash stored on the device.

$userKey= crypt($password, "$".$algo."$".$salt);

if($pwFileKey == $userKey)
{
    $pwCorrect = true;
}
  • $password comes from the HTTP POST request and is passed to the PasswordCorrect() function without any input validation or filtering
  • $algo and $salt are pulled Based on inspection of various firmware versions, this vulnerability appears to impact all versions from the current and going back to at least 10 and likely earlier.from the password file and then concatenated back together (with the leading $ added before the algo and salt)
    • algo will be 6
    • salt will be the next 16 chars

The result will be something like crypt("wago","$6$nJ68diwYtzvoGdmO"), which returns $6$nJ68diwYtzvoGdmO$riWD40K1ygPswo/bW0EhwGCNwpWw1mVaHKGXoiLU4vydECe2pXqpZAVkl0JM9GoibmyCGOTCp5Fk8hL8jGoFA0 (the default for the admin user). The vulnerable code is nested in several if statements but can be reached by abusing regular expressions as in TALOS-2019-0923 (CVE-2019-5134).

An attacker may analyze the HTTP response delay of various inputs and infer which characters are in both the salt and the hash. The submitted password is irrelevant and can be used to increase the processing time of crypt() by passing a large value (500 characters was sufficient in testing).

By default the login.php file sets /etc/lighttpd/lighttpd-htpasswd.user as the WBM password file with the following code:

define("PASSWORD_FILENAME", "/etc/lighttpd/lighttpd-htpasswd.user");
#define("PASSWORD_FILENAME", "/etc/shadow");

If the configuration of WBM has been changed to use system credentials instead of lighttpd, an attacker will be able to retrieve hashed credentials for any user in the /etc/shadow file. A successful password cracking attack against a system user will give the attacker access to the underlying operating system, significantly increasing the severity of this vulnerability (9.0 - CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H)

Mitigation

The WBM credentials are salted and hashed using the SHA-512 algorithm and are unusable in the extracted format. However, the salt can be extracted along with the hash, significantly reducing resistance to password cracking attacks. To mitigate the risk of an attacker obtaining credentials by cracking stolen password hashes, ensure strong passwords are used.

When developing PHP applications, the hash_equals() function is intended to be safe from timing attacks and should be used in place of crypt() when comparing password hashes.

Timeline

2019-10-28 - Vendor Disclosure
2019-10-31 - Vendor passed to CERT@VDE for coordination/handling
2019-12-16 - Disclosure deadline extended
2020-01-28 - Talos discussion about vulnerabilities with Vendor
2020-03-09 - Public Release

Credit

Discovered by Patrick DeSantis and Lilith [-_-]; of Cisco Talos.