Contents

OpenBSD Let Attackers Log In With an Empty Password for 27 Years

 

Ethical Hacking Complete Course Zero to Expert

Hack like black hat hackers. Penetration testing, Kali Linux, WiFi and web hacking, and the hacker mindset behind it.

→ Take the full course
 
Contents

A 27-year-old flaw in OpenBSD let attackers bypass its PPP login with nothing more than an empty username and an empty password. Hand a vulnerable system a blank name and a blank password, and its own login check treated that as a perfect match and let the connection in.

The problem sits in the part of OpenBSD that handles PPP, the protocol behind many DSL and fiber connections, usually carried through PPPoE. When two machines set up that kind of link, one side can ask the other to prove who it is. One of the older ways to do that is PAP, the Password Authentication Protocol. One machine sends a name and a password, the other checks them against what it has stored, and if they match the link comes up.

OpenBSD checked those credentials with a small function called bcmp. It compares two pieces of memory byte by byte. You hand it two buffers and a number for how many bytes to compare, and it reports whether those bytes are the same. That number is the problem. OpenBSD read it straight from the packet the other machine sent, and that machine can set it to anything, including zero.

Ask bcmp to compare zero bytes and it has nothing to look at, so it says the two buffers are identical. Comparing nothing always comes back as a match. On its own that is correct and documented behavior. The mistake was letting the other side pick that number.

Here is the check that decided whether a login was good, in a function called sppp_pap_input():

1
2
3
4
if (name_len > AUTHMAXLEN ||
    passwd_len > AUTHMAXLEN ||
    bcmp(name, sp->hisauth.name, name_len) != 0 ||
    bcmp(passwd, sp->hisauth.secret, passwd_len) != 0) {

name_len and passwd_len are the lengths pulled from the incoming packet. The only check was an upper limit, AUTHMAXLEN, which throws out anything longer than 255 characters. Nothing looked at the low end. Send a name length of zero and a password length of zero, and both bcmp calls compare nothing, both come back as a match, the failure branch never runs, and OpenBSD sends back a PAP_ACK. The login went through without a single real credential.

Argus, the security team that found this, wrote a proof of concept that does it end to end. The script pretends to be a PPPoE server. It runs through the normal handshake, then sends a PAP request with both lengths set to zero. OpenBSD accepts it, and the connection comes up:

1
2
3
4
PAP_ACK received with empty credentials
IPCP Config-Ack received, link is UP
ICMP echo reply received
FULL LINK ESTABLISHED

From there, a rogue PPPoE server on the same local network can pose as the real one, and OpenBSD routes its traffic through the attacker. Argus tested this against OpenBSD 7.6 in a virtual machine. An incoming PPPoE packet reaches the broken check through a short path inside the kernel: pppoe_data_input, then pppoeintr, then sppp_input, then sppp_pap_input. A packet sent over the network sets it off, not a local test.

The same length field opens a second hole. If the attacker claims a name longer than the credential OpenBSD has stored, bcmp reads past the end of that stored value into whatever kernel memory sits next to it. A stored secret of eight bytes with a claimed length of 200 makes bcmp read 192 bytes beyond it, into nearby kernel memory. This second part is newer than the login bypass. It dates to February 2009, when OpenBSD changed how it stores those credentials, from a fixed block to memory sized to each one, and that let the comparison run past the end.

The broken code went into OpenBSD on 1 July 1999, imported from FreeBSD. FreeBSD had taken it from an implementation written by Serge Vakulenko at Cronyx Engineering in the mid-1990s. So the same comparison logic ended up in OpenBSD, FreeBSD and NetBSD, from one shared ancestor.

FreeBSD and NetBSD still run that same PAP code today, and both check the length first. FreeBSD compares the claimed name length against the stored length before it runs the byte comparison, so a zero-length name gets rejected right away. NetBSD does the same with its own length field. OpenBSD’s PAP path left that check out and stayed that way for 27 years. Its own CHAP code, in the very same file, already did it right. PAP just never got it.

Argus reported the bug to OpenBSD on 12 June 2026. The fix went in two days later, on 14 June, and it copies what CHAP already did, putting an exact length check ahead of the byte comparison:

1
2
3
4
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) {

Now a zero-length name only matches if the stored name is also empty, and the comparison stops at the real length of what is stored. That one change shuts both the bypass and the memory leak.

This is not something that hits a normal OpenBSD machine. It only matters when OpenBSD is the side checking the password on a PPP or PPPoE link, which is not how a standard setup runs, and the attacker has to sit on the same local network to send the packets. PAP was a weak choice to begin with, because it sends the name and password as plain text, so someone watching the wire can read them. So what is left is one missing length check that sat in the code for 27 years, in a system people pick precisely because its code gets read so carefully. The bug only got an official number on 17 June, three days after the fix: CVE-2026-55706, scored 5.8 out of 10, which lands in the medium range. Low enough, and niche enough, that it slipped past the news while the code, the commit and the proof of concept were sitting out in the open.

What to do if you run OpenBSD on a PPP or PPPoE link:

  • → Switch from PAP to CHAP for authentication where the link supports it
  • → Apply the patch with syspatch, or move to a build that includes the 14 June fix
  • → Keep PAP authentication off any network segment outside your control

The attack here is a rogue server on the local network posing as the real one and bypassing a weak authentication check to get in. Finding services that expose weak authentication, attacking networks where devices trust each other too much, and turning that into a foothold, that is the kind of work my ethical hacking course covers step by step:

Hacking is not a hobby but a way of life.

Sources:

Argus | OpenBSD | NVD

 
NEWSLETTER

Stay updated

Get the latest posts in your inbox every week. Ethical hacking, security news, tutorials, and everything that catches my attention. If that sounds useful, drop your email below.

By Bulls Eye

Jolanda de koff • emaildonate

My name is Jolanda de Koff and on the internet, I'm also known as Bulls Eye. Ethical Hacker, Penetration tester, Researcher, Programmer, Self Learner, and forever n00b. Not necessarily in that order. Like to make my own hacking tools and I sometimes share them with you. "You can create art & beauty with a computer and Hacking is not a hobby but a way of life ...

I ♥ open-source and Linux