The versions below were either tested or verified to be vulnerable by Talos or confirmed to be vulnerable by the vendor.
Peplink Surf SOHO HW1 v6.3.5 (in QEMU)
Surf SOHO HW1 - https://www.peplink.com/products/soho-series-surf/
3.4 - CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:C/C:L/I:N/A:N
CWE-80 - Improper Neutralization of Script-Related HTML Tags in a Web Page (Basic XSS)
The Surf series of SOHO routers is marketed as an entry-level router for use at home. It provides networking via USB cellular modems, ethernet and Wi-Fi. The device can host a VPN and supports Wi-Fi meshing.
The device hosts a web interface for administrative configuration. A stored XSS vulnerability exists in the handling of requests destined for the
/cgi-bin/MANGA/upload_brand.cgi endpoint which are intended to interact with the logo and branding management feature. This endpoint is accessible only after successfully authenticating as a user with write privileges on the device. The HTTP POST request must have a parameter,
mode, whose value is set to
api in order to reach the vulnerable code. The OEM of the device must be VISLINK, or the vulnerable brand upload feature will be disabled and inaccessible.
The vulnerable function is located in the file
upload_brand.cgi at offset
0x40d390 in firmware version 6.3.5, and we refer to it as
handle_brand_upload. An annotated decompilation of the function is included for reference.
Upon receiving a properly formed HTTP request, and validating that the OEM of the device is VISLINK,
handle_brand_upload is called. Within this function, the attacker-controlled POST parameters of the request are extracted (
brand_web_name specifically is checked against a blocklist to ensure that none of six prohibited values are contained within the submitted value at
brand_web_name passes these checks, then the values are persisted to the device’s configuration files.
It is not necessary to know the full implementation details for the “taglist” structure except to say that values put into a taglist via
), saved via
) and persisted into the brand configuration file through
), will be made available to any software on the system.
These particular values are used to populate the branding for the web interface, and they’re placed into the HTML within the
index.cgi binary in a function named
load_leftmenu. This function is located at offset
0x40a6a4 and the relevant portion of a decompilation of the function is included below.
, the branding taglist is loaded from
/etc/brand.conf and three of the branding tags are loaded. Then, at
, the HTML template for the menu is loaded from disk, and the branding data is used to populate the templated values. While the branding data is passed through
web_link_url, due to the way in which the template is written. The template file,
htmlString, and the
<script> itself. In this instance, only
2023-06-26 - Initial Vendor Contact
2023-06-27 - Vendor Disclosure
2023-10-11 - Public Release
Discovered by Matt Wiseman of Cisco Talos.