Recently, Cisco revealed a critical vulnerability CVE-2025-20188 in its IOS XE Wireless Controller Software, affecting version 17.12.03 and earlier. CVE-2025-20188 stems from an unauthenticated arbitrary file upload mechanism, is linked to a hard-coded JSON Web Token (JWT) in the system.

This vulnerability impacts Cisco’s widely deployed Wireless LAN Controller (WLC), a core enterprise solution integrated with IOS XE for managing and scaling wireless networks across branch and campus environments.

Investigating CVE-2025-20188

To understand the nature of the CVE-2025-20188 vulnerability, researchers from horizon3.ai began by comparing two firmware versions: C9800-CL-universalk9.17.12.03.iso (vulnerable) and C9800-CL-universalk9.17.12.04.iso (patched). Within each ISO, they discovered two .pkg files and yielded very limited information, but using binwalk, the researchers were able to extract and inspect the file systems.

Key application files were located in /var/www and /var/scripts, indicating the use of OpenResty, a Lua-based web platform built on Nginx. Using Visual Studio Code’s diffing tools, researchers isolated significant differences in two Lua scripts: ewlc_jwt_verify.lua and ewlc_jwt_upload_files.lua located under /var/scripts/lua/features/.

These scripts handle JWT verification and file uploads, pointing directly to the core of the exploit. A simple grep search through the file system led to relevant configuration entries in the Nginx config located at:

/usr/binos/conf/nginx-conf/https-only/ap-conf/ewlc_auth_jwt.conf

This file revealed two important endpoints (/aparchive/upload and /ap_spec_rec/upload/) that use the two Lua scripts for access verification and file upload processing.

Hard-Coded JWT Mechanism

The ewlc_jwt_verify.lua script retrieves a JWT token from either the jwt URL parameter or the Cookie header, then attempts to validate it using a key from /tmp/nginx_jwt_key. If the key is not found, the script sets the secret to “notfound” effectively allowing any token signed with “notfound” as the key to pass verification.

To trace the generation of the JWT, the team analyzed another script, ewlc_jwt_get.lua, which reads (or creates) the same secret key and signs a JWT using the resty.jwt library. The key insight was that if /tmp/nginx_jwt_key doesn’t exist, the system generates a new one and writes it to that path unless the script fails or the key is removed, resulting in the default “notfound” fallback.

To find the origin of the JWT’s JWTReqId value, reverse engineering tools were used. A single reference to the relevant function was discovered in a shared library (libewlc_apmgr.so). This led to the header value cdb_token_request_id1, which was later used to manually generate a valid JWT token using Python.

Exploiting CVE-2025-20188

With a valid JWT, the researchers targeted the /ap_spec_rec/upload/ endpoint. Initial attempts failed until they enabled the Out-of-Band AP Image Download feature, found under Configuration → Wireless Global → AP Image Upgradein the WLC web UI.

Once the feature was enabled, the upload endpoint on port 8443 became active. Crafting a JWT with the known fallback secret, the researchers successfully received responses, confirming access to the upload functionality.

The upload logic in ewlc_jwt_upload_files.lua writes incoming files to the path specified by the upload_file_dst_path variable. Critically, no validation was present to prevent path traversal using ../, allowing files to be written anywhere on the filesystem.

While file upload alone is severe, the researchers dug deeper to identify a path to remote code execution. They discovered a service script (pvp.sh) using inotifywait to monitor specific directories for file changes, triggering actions based on configurations.

By overwriting the service’s config file with custom commands and uploading a file to trigger a reload, the researchers executed arbitrary code.

You can now understand that,

  • On freshly installed WLC systems, port 8443 was often open by default even if the Out-of-Band AP Image Download feature wasn’t explicitly enabled.

  • This suggests that vulnerable endpoints may be exposed on default installations of C9800 series controllers.

Mitigation Recommendations

Cisco has already patched the vulnerability in version 17.12.04 and strongly recommends upgrading to the latest software version. For environments where immediate upgrades are not feasible, administrators should disable the Out-of-Band AP Image Download feature. With this feature disabled, WLC uses the CAPWAP method for AP image transfers, which doesn’t rely on the vulnerable upload mechanism.

For More Info: hxxps[://]horizon3[.]ai/attack-research/attack-blogs/cisco-ios-xe-wlc-arbitrary-file-upload-vulnerability-cve-2025-20188-analysis/

Follow cybersecurity88 on X and LinkedIn for the latest cybersecurity news