Security Advisory: Unauthenticated Configuration Export in Multiple WAGO ProductsDatum: 16.01.2023
Autor: ONEKEY / CERTAINITY Reasearch Team
As shown in our previous security advisory for the Asus M25 NAS from our research cooperation with ONEKEY, we recently introduced a “zero-day identification” module that performs static code analysis on proprietary applications found within firmware uploaded to ONEKEY’s platform.
This module reported two potential issues within a WAGO Series PFC100 configuration API: a path traversal and a command injection vulnerability. The command injection turned out to be a false positive (we strengthened our analysis capabilities since then) but it got us to investigate a specific PHP file where we identified that the authentication and authorization code blocks were commented.
We verified that it could lead to an unauthenticated configuration export using an emulated device and reported both this issue and the path traversal to WAGO.
Unauthenticated Configuration Export
Affected vendor & product | Series WAGO PFC100 (750-81xx/xxx-xxx) Series WAGO PFC200 (750-82xx/xxx-xxx) WAGO Compact Controller CC100 (751-9301) WAGO Edge Controller (752-8303/8000-002) Series WAGO Touch Panel 600 Standard Line (762-4xxx) Series WAGO Touch Panel 600 Advanced Line (762-5xxx) Series WAGO Touch Panel 600 Marine Line (762-6xxx) |
Vendor Advisory | |
Vulnerable version | Firmware versions >= 16 and <= 22. |
Fixed version | We recommend all affected users to install FW22 Patch 1 or higher. |
CVE IDs | |
Impact (CVSS) | 4.3 (medium) (CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N) |
Credit | Q. Kaiser, ONEKEY Research Lab |
Summary
The configuration API of the web-based management interface (WBM) of WAGOs programmable logic controller (PLC) does not require authentication and offers the download of files in a specific folder. This folder typically contains backups created since the last reboot, which might hold sensitive data.
Impact
A successful exploit could allow the attacker to download a copy of the running firmware or the VPN configuration. Both these files would hold sensitive information such as user credentials or cryptographic material.
Note that to be able to download the files, they must have been generated by a legitimate user since the last reboot.
Description
The WAGO web admin interface is written in
PHP and has a page allowing for VPN configuration or firmware export found
at /var/www/wbm/php/file_transfer/offer_download.php
. Within this
file, lines 30 to 46 are commented using a multi-line comment. This effectively
disables the authentication and authorization checks that were supposed to be
performed on those lines.
<?php include_once"wbm_lib.inc.php"; include_once __DIR__.'/wbm_lib.inc.php'; include_once __DIR__.'/file_transfer.inc.php'; include_once __DIR__.'/../authentication/session_lifetime.inc.php'; use transfer\FileTransfer; // define constants /* define("DOWNLOAD_DIR", "/tmp"); define("UPLOAD_DIR", "/tmp"); */ define("DOWNLOAD_FILENAME_FRAGMENT", "firmware_backup"); // Offer backup download file. Function takes the first file in download directory (there should be only one), // transfers it to browser and deletes the file afterwards. function OfferDownload() { $status = SUCCESS; $errorText = ""; $transfer; // optional, of type FileTransfer /* // check for correct session and reset session timeout $status = Session_HandleSessionLifeTime($_GET["csrf_id"],false); if(SUCCESS != $status) { $errorText = Session_GetErrorTxt($status); } else if(!isset($_SESSION["username"]) || USER_ADMIN != $_SESSION["username"]) { $status = ACCESS_NOT_ALLOWED; $errorText = "Access not allowed."; } // check if folder is given else */ { if(!isset($_GET["download_dir"]))
Authenticated Path Traversal (Bonus)
WAGO does not consider the authenticated path traversal to be a vulnerability since it can only be triggered by a user with administrative privileges. A user with these privileges can simply create a backup of the running firmware and download it, making the path traversal and possibility to download arbitrary files useless. We fully agree with that assessment, but still wanted to show how it was found.
The path traversal was reported as affecting
download.php. As we can see in the screenshot below, the $downloadPath
value is used by
a fopen
call.
This $downloadPath
is directly obtained from the GET parameter “download”:
$downloadPath = ''; if (isset($_GET['download'])) { $downloadPath = $_GET['download']; // check file exists if(!file_exists($downloadPath)) { die_with_response(200, [ 'error' => new WBMError(ERROR_GROUP_FILE_TRANSFER, ERROR_CODE_DOWNLOAD_FILE_DOES_NOT_EXIST, 'File does not exist') ]); } // check access rights if(!is_readable($downloadPath)) { die_with_response(200, [ 'error' => new WBMError(ERROR_GROUP_FILE_TRANSFER, ERROR_CODE_DOWNLOAD_FILE_NOT_READABLE, 'File is not readable') ]); } }
The file content is then returned to the user:
$file = fopen($downloadPath, 'r'); if(!$file) { die_with_response(200, [ 'error' => new WBMError(ERROR_GROUP_FILE_TRANSFER, ERROR_CODE_DOWNLOAD_FILE_NOT_READABLE, 'File is not readable') ]); } // put fitting filetype to header header("Content-Type: application/octet-stream"); // send header with proposal of fitting filename header(sprintf("Content-Disposition: attachment; filename=\"%s\"", basename($downloadPath))); // send file size header('Content-Length: '.filesize($downloadPath)); // before sending the file content, add a cookie to tell the frontend that the download will be started setcookie("download($downloadPath)", 'started', 0, '/'); flush(); // read and send file chunkwise while (!feof($file)) { print fread($file, 1024*1024); // read 1MiB... flush(); // ... and send to browser } fclose($file);
Key Takeaways
Having the possibility to automatically identify unknown high-risk and critical vulnerabilities is a powerful capability have – a super-power both for operators and manufacturers of IACS. Operators get a chance to efficiently validate vendor claims on a low-effort basis and security manufacturers can fix such vulnerabilities before even shipping devices to their clients. While it is important to be as confident as possible about potential vulnerabilities, sometimes something that just looks like a vulnerability turns out to reveal a vulnerable area of the application.
Timeline
2022-10-17 – Sent coordinated disclosure request to psirt@wago.com
2022-10-17 – Answer from WAGO PSIRT (Product Security Incident Response Team), establishment of secure communication channel.
2022-10-21 – First feedback from WAGO PSIRT on reproduction.
2022-10-21 – Second feedback from WAGO PSIRT on authenticated path traversal.
2022-11-10 – WAGO PSIRT provides us with CVE (Common Vulnerabilities and Exposures) ID and CVSS (Common Vulnerability Scoring System) score, start coordination with CERT@VDE
2022-12-08 – WAGO PSIRT shares draft advisory with us and CERT@VDE
2023-01-12– CERT@VDE releases WAGO advisory
2023-01-16 – ONEKEY & CERTAINITY releases its advisory