GCVE Workshop - 22 September 2026 (14:00-18:00), Luxembourg Before The Vulnopticon Conference - Registration

GCVE-1988-2026-0362

Vulnerability from gna-1988 – Published: 2026-09-11 07:55 – Updated: 2026-09-11 11:31
VLAI
Title
OpenBSD sppp_pap_input: PAP authentication bypass
Summary
------------------------------------------------------------------------ OpenBSD sppp_pap_input: PAP Authentication Bypass via Zero-Length bcmp ------------------------------------------------------------------------ Affected:  OpenBSD all versions through 7.6 (fixed in -current) Vendor:    OpenBSD Severity:  High Reporter:  Argus Date:      2026-06-16 1. SUMMARY ========== The sppp_pap_input() function in sys/net/if_spppsubr.c uses the attacker-controlled name_len and passwd_len fields from the incoming PAP frame directly as the comparison length for bcmp() against configured credentials. When both fields are set to zero, bcmp() returns 0 unconditionally (bcmp with length 0 always succeeds). The existing upper-bound guard (> AUTHMAXLEN) allows zero through. As a result, a PAP Auth-Request with name_len=0 and passwd_len=0 passes credential validation and triggers a PAP_ACK, authenticating the peer without any knowledge of the configured username or password. A secondary kernel heap over-read exists via the same root cause: supplying a name_len larger than the allocation of the stored credential causes bcmp to read past the heap object. 2. AFFECTED VERSIONS ==================== The bcmp comparison pattern was introduced with the original sppp code import on 1999-07-01 (commit bda3414e, "lmc driver; ported by chris () dqc org"). The zero-length bypass has been exploitable since that date. In February 2009 (commit 9c2f3d605fc), auth credential fields were changed from fixed-size struct arrays to dynamically allocated malloc(strlen()+1), and the bounds check was changed to > AUTHMAXLEN (256). This decoupled the allocation size from the comparison bound, enabling the heap over-read. Confirmed against OpenBSD 7.6 (amd64) in QEMU/KVM. 3. DETAILS ========== Vulnerable code (sys/net/if_spppsubr.c, sppp_pap_input):   if (name_len > AUTHMAXLEN ||       passwd_len > AUTHMAXLEN ||       bcmp(name, sp->hisauth.name, name_len) != 0 ||       bcmp(passwd, sp->hisauth.secret, passwd_len) != 0) {           /* authentication failed */ name_len and passwd_len are parsed directly from the PAP frame payload. bcmp(a, b, 0) always returns 0. The > AUTHMAXLEN guard rejects values above 255 but permits zero. The CHAP handler in the same file already had the correct pattern with an exact-length pre-check:   if (name_len != strlen(sp->hisauth.name)       || bcmp(name, sp->hisauth.name, name_len) != 0) { The PAP handler never received the same treatment. 4. REACHABILITY =============== Both bugs are reachable via the PPPoE data path:   pppoe_data_input -> pppoeintr -> sppp_input -> sppp_pap_input Precondition: the target system must be configured as a PAP authenticator (e.g. ifconfig pppoe0 peerproto pap peername <x> peerkey <y>). The attacker does not need to know any credentials. 5. IMPACT ========= An attacker on the same network segment can authenticate to a PPPoE interface without credentials, establishing a full network-layer link (LCP -> PAP -> IPCP -> IP). When OpenBSD acts as a PPPoE client with mutual authentication, a rogue server in the same broadcast domain can exploit the bypass to impersonate a legitimate server, causing OpenBSD to route traffic through the attacker's endpoint. 6. PROOF OF CONCEPT =================== A Python PoC acts as a PPPoE server, completes discovery and LCP negotiation, then sends a PAP Auth-Request with name_len=0 and passwd_len=0. Result:   PAP_ACK received with empty credentials   VM accepted name_len=0, passwd_len=0 as valid auth.   IPCP Config-Ack received - link is UP   ICMP echo reply from 10.0.0.1   FULL LINK ESTABLISHED PoC and full technical report:   https://blog.argus-systems.ai/blog/openbsd-pap-27-year-auth-bypass.html 7. FIX ====== Fixed in -current by mvs on 2026-06-14. The fix mirrors the CHAP handler's exact-length pre-check:   if (name_len != strlen(sp->hisauth.name) ||       passwd_len != strlen(sp->hisauth.secret) ||       bcmp(name, sp->hisauth.name, name_len) != 0 ||       bcmp(passwd, sp->hisauth.secret, passwd_len) != 0) { Fix commit: https://github.com/openbsd/src/commit/076e2b1c1fc4ac0883a72d3544131ad5cee7adf8 8. TIMELINE ===========   2026-06-12  Reported to security () openbsd org with PoC   2026-06-14  Fix committed to -current 9. CREDIT ========= Discovered and reported by Argus (https://byteray.co.uk/). 10. REFERENCES ============== Advisory:   https://pop.argus-systems.ai/advisory/adv-038.html Blog post: https://blog.argus-systems.ai/blog/openbsd-pap-27-year-auth-bypass.html Proof of concept:   https://pop.argus-systems.ai/attachments/poc-001-pap-bypass.py _______________________________________________ Sent through the Full Disclosure mailing list https://nmap.org/mailman/listinfo/fulldisclosure Web Archives & RSS: https://seclists.org/fulldisclosure/
Severity
No CVSS data available.
Impacted products
Vendor Product Version CPE status
Openbsd sppp_pap_input PAP Affected: unknown
guessed Create a notification for this product.
Credits

{
  "containers": {
    "cna": {
      "affected": [
        {
          "product": "sppp_pap_input PAP",
          "vendor": "Openbsd",
          "versions": [
            {
              "status": "affected",
              "version": "unknown"
            }
          ]
        }
      ],
      "credits": [
        {
          "lang": "en",
          "type": "finder",
          "value": "shj"
        }
      ],
      "descriptions": [
        {
          "lang": "en",
          "value": "------------------------------------------------------------------------\nOpenBSD sppp_pap_input: PAP Authentication Bypass via Zero-Length bcmp\n------------------------------------------------------------------------\n\nAffected:\u00a0 OpenBSD all versions through 7.6 (fixed in -current)\nVendor:\u00a0 \u00a0 OpenBSD\nSeverity:\u00a0 High\nReporter:\u00a0 Argus\nDate:\u00a0 \u00a0 \u00a0 2026-06-16\n\n\n1. SUMMARY\n==========\n\nThe sppp_pap_input() function in sys/net/if_spppsubr.c uses the\nattacker-controlled name_len and passwd_len fields from the incoming\nPAP frame directly as the comparison length for bcmp() against\nconfigured credentials.\n\nWhen both fields are set to zero, bcmp() returns 0 unconditionally\n(bcmp with length 0 always succeeds). The existing upper-bound guard\n(\u003e AUTHMAXLEN) allows zero through. As a result, a PAP Auth-Request\nwith name_len=0 and passwd_len=0 passes credential validation and\ntriggers a PAP_ACK, authenticating the peer without any knowledge of\nthe configured username or password.\n\nA secondary kernel heap over-read exists via the same root cause:\nsupplying a name_len larger than the allocation of the stored\ncredential causes bcmp to read past the heap object.\n\n\n2. AFFECTED VERSIONS\n====================\n\nThe bcmp comparison pattern was introduced with the original sppp\ncode import on 1999-07-01 (commit bda3414e, \"lmc driver; ported by\nchris () dqc org\"). The zero-length bypass has been exploitable since\nthat date.\n\nIn February 2009 (commit 9c2f3d605fc), auth credential fields were\nchanged from fixed-size struct arrays to dynamically allocated\nmalloc(strlen()+1), and the bounds check was changed to\n\u003e AUTHMAXLEN (256). This decoupled the allocation size from the\ncomparison bound, enabling the heap over-read.\n\nConfirmed against OpenBSD 7.6 (amd64) in QEMU/KVM.\n\n\n3. DETAILS\n==========\n\nVulnerable code (sys/net/if_spppsubr.c, sppp_pap_input):\n\n\u00a0 if (name_len \u003e AUTHMAXLEN ||\n\u00a0 \u00a0 \u00a0 passwd_len \u003e AUTHMAXLEN ||\n\u00a0 \u00a0 \u00a0 bcmp(name, sp-\u003ehisauth.name, name_len) != 0 ||\n\u00a0 \u00a0 \u00a0 bcmp(passwd, sp-\u003ehisauth.secret, passwd_len) != 0) {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 /* authentication failed */\n\nname_len and passwd_len are parsed directly from the PAP frame\npayload. bcmp(a, b, 0) always returns 0. The \u003e AUTHMAXLEN guard\nrejects values above 255 but permits zero.\n\nThe CHAP handler in the same file already had the correct pattern\nwith an exact-length pre-check:\n\n\u00a0 if (name_len != strlen(sp-\u003ehisauth.name)\n\u00a0 \u00a0 \u00a0 || bcmp(name, sp-\u003ehisauth.name, name_len) != 0) {\n\nThe PAP handler never received the same treatment.\n\n\n4. REACHABILITY\n===============\n\nBoth bugs are reachable via the PPPoE data path:\n\n\u00a0 pppoe_data_input -\u003e pppoeintr -\u003e sppp_input -\u003e sppp_pap_input\n\nPrecondition: the target system must be configured as a PAP\nauthenticator (e.g. ifconfig pppoe0 peerproto pap peername \u003cx\u003e\npeerkey \u003cy\u003e). The attacker does not need to know any credentials.\n\n\n5. IMPACT\n=========\n\nAn attacker on the same network segment can authenticate to a PPPoE\ninterface without credentials, establishing a full network-layer\nlink (LCP -\u003e PAP -\u003e IPCP -\u003e IP).\n\nWhen OpenBSD acts as a PPPoE client with mutual authentication, a\nrogue server in the same broadcast domain can exploit the bypass to\nimpersonate a legitimate server, causing OpenBSD to route traffic\nthrough the attacker\u0027s endpoint.\n\n\n6. PROOF OF CONCEPT\n===================\n\nA Python PoC acts as a PPPoE server, completes discovery and\nLCP negotiation, then sends a PAP Auth-Request with name_len=0 and\npasswd_len=0.\n\nResult:\n\n\u00a0 PAP_ACK received with empty credentials\n\u00a0 VM accepted name_len=0, passwd_len=0 as valid auth.\n\n\u00a0 IPCP Config-Ack received - link is UP\n\u00a0 ICMP echo reply from 10.0.0.1\n\n\u00a0 FULL LINK ESTABLISHED\n\nPoC and full technical report:\n\u00a0\u00a0https://blog.argus-systems.ai/blog/openbsd-pap-27-year-auth-bypass.html\n\n\n7. FIX\n======\n\nFixed in -current by mvs on 2026-06-14. The fix mirrors the CHAP\nhandler\u0027s exact-length pre-check:\n\n\u00a0 if (name_len != strlen(sp-\u003ehisauth.name) ||\n\u00a0 \u00a0 \u00a0 passwd_len != strlen(sp-\u003ehisauth.secret) ||\n\u00a0 \u00a0 \u00a0 bcmp(name, sp-\u003ehisauth.name, name_len) != 0 ||\n\u00a0 \u00a0 \u00a0 bcmp(passwd, sp-\u003ehisauth.secret, passwd_len) != 0) {\n\nFix commit:\nhttps://github.com/openbsd/src/commit/076e2b1c1fc4ac0883a72d3544131ad5cee7adf8\n\n\n8. TIMELINE\n===========\n\n\u00a0 2026-06-12\u00a0 Reported to security () openbsd org with PoC\n\u00a0 2026-06-14\u00a0 Fix committed to -current\n\n\n9. CREDIT\n=========\n\nDiscovered and reported by Argus (https://byteray.co.uk/).\n\n\n10. REFERENCES\n==============\n\nAdvisory:\n\u00a0 https://pop.argus-systems.ai/advisory/adv-038.html\n\nBlog post:\nhttps://blog.argus-systems.ai/blog/openbsd-pap-27-year-auth-bypass.html\n\nProof of concept:\n\u00a0 https://pop.argus-systems.ai/attachments/poc-001-pap-bypass.py\n\n_______________________________________________\nSent through the Full Disclosure mailing list\nhttps://nmap.org/mailman/listinfo/fulldisclosure\nWeb Archives \u0026 RSS: https://seclists.org/fulldisclosure/"
        }
      ],
      "providerMetadata": {
        "dateUpdated": "2026-09-11T11:31:48Z",
        "orgId": "4e2abfbf-4a2a-4b76-a4e0-d77c18ba156c",
        "shortName": "VULNARCHIVE"
      },
      "references": [
        {
          "tags": [
            "technical-description",
            "exploit"
          ],
          "url": "https://vuln.freearchive.org/archive/full-disclosure/2026/Jun/15"
        },
        {
          "tags": [
            "technical-description"
          ],
          "url": "https://seclists.org/fulldisclosure/2026/Jun/15"
        },
        {
          "url": "https://blog.argus-systems.ai/blog/openbsd-pap-27-year-auth-bypass.html"
        },
        {
          "url": "https://byteray.co.uk/"
        },
        {
          "url": "https://github.com/openbsd/src/commit/076e2b1c1fc4ac0883a72d3544131ad5cee7adf8"
        },
        {
          "url": "https://nmap.org/mailman/listinfo/fulldisclosure"
        },
        {
          "url": "https://pop.argus-systems.ai/advisory/adv-038.html"
        },
        {
          "url": "https://pop.argus-systems.ai/attachments/poc-001-pap-bypass.py"
        },
        {
          "url": "https://seclists.org/fulldisclosure/"
        }
      ],
      "source": {
        "defect": [
          "https://seclists.org/fulldisclosure/2026/Jun/15"
        ],
        "discovery": "EXTERNAL"
      },
      "title": "OpenBSD sppp_pap_input: PAP authentication bypass",
      "x_gcve": [
        {
          "recordType": "advisory",
          "relationships": [],
          "vulnId": "GCVE-1988-2026-0362",
          "x_vulnarchive": {
            "archiveUrl": "https://vuln.freearchive.org/archive/full-disclosure/2026/Jun/15",
            "automated": true,
            "contentSha256": "e9970fb07c7e498304d6f1ffb1e4aa8eb8fc2d3e988893327f0a72abe1bfbdc1",
            "evidenceScore": 9,
            "messageId": "",
            "originalUrl": "https://seclists.org/fulldisclosure/2026/Jun/15",
            "policy": "vulnarchive-1",
            "sourceFormat": "text/html",
            "sourcePublishedAt": "2026-06-16T19:27:44Z"
          }
        }
      ]
    }
  },
  "cveMetadata": {
    "assignerOrgId": "4e2abfbf-4a2a-4b76-a4e0-d77c18ba156c",
    "assignerShortName": "VULNARCHIVE",
    "datePublished": "2026-09-11T07:55:57Z",
    "dateUpdated": "2026-09-11T11:31:48Z",
    "state": "PUBLISHED",
    "vulnId": "GCVE-1988-2026-0362"
  },
  "dataType": "CVE_RECORD",
  "dataVersion": "5.2"
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.

Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…

Loading…