OpenSSH Flaw Lets Attackers Log Into Password-Disabled Linux Accounts (bleepingcomputer.com) 68
A newly disclosed OpenSSH flaw dubbed "*sshole" can allow attackers to log in to password-disabled accounts on certain musl-based Linux systems simply by submitting a password longer than 256 bytes. "Apparently certain varieties of musl Linux (Alpine, OpenWrt, Buildroot, Yocto, etc.) have had this OpenSSH vulnerability for about a decade," writes longtime Slashdot reader AlteredEgg. "Upgrade now!" BleepingComputer reports: Security researcher Ozgun Kultekin, who discovered and released details on the vulnerability today, says the flaw has existed since 2016 and stems from how OpenSSH handles password verification errors on systems using the musl C library. Linux accounts can be configured to prevent password logins by replacing their password hash with an asterisk (*) in the /etc/shadow file. Because this is not a valid password hash, no password should allow access to those accounts. However, a patch introduced in OpenSSH in 2016 to fix a username enumeration vulnerability tracked as CVE-2016-6210 changed how OpenSSH handled accounts without usable password hashes.
To prevent attackers from identifying valid usernames through different response times, OpenSSH was modified to perform password hashing even when an account had no usable password hash, including accounts configured with * to block password logins. The problem is that the musl C library's crypt() function also returns * when password hashing fails, including when a submitted password exceeds its 256-byte limit. This means an attacker can submit an oversized password and cause OpenSSH to compare the returned * against the account's stored *, resulting in a successful login.
To be clear, the flaw does not allow attackers to bypass passwords on accounts with valid password hashes. [...] Admins who can't immediately install the update can mitigate the issue by turning off SSH password authentication with PasswordAuthentication no in their SSH server configuration and restarting SSH. Kultekin says admins can also check for signs of exploitation by examining SSH authentication logs for password-based logins for accounts that should not allow them.
To prevent attackers from identifying valid usernames through different response times, OpenSSH was modified to perform password hashing even when an account had no usable password hash, including accounts configured with * to block password logins. The problem is that the musl C library's crypt() function also returns * when password hashing fails, including when a submitted password exceeds its 256-byte limit. This means an attacker can submit an oversized password and cause OpenSSH to compare the returned * against the account's stored *, resulting in a successful login.
To be clear, the flaw does not allow attackers to bypass passwords on accounts with valid password hashes. [...] Admins who can't immediately install the update can mitigate the issue by turning off SSH password authentication with PasswordAuthentication no in their SSH server configuration and restarting SSH. Kultekin says admins can also check for signs of exploitation by examining SSH authentication logs for password-based logins for accounts that should not allow them.
UNIX-style passwords (Score:3)
Re:UNIX-style passwords (Score:5, Interesting)
On Hacker News the headline for a similar article was "AI is forcing us to pay off 40 years of technical debt".
I think that sums it up well. Like you said, it's been known for 20 years ... and yet it's still relevant today. AI is forcing us to deal with our tech debt.
Re:UNIX-style passwords (Score:4, Interesting)
There is nothing wrong using passwords for ssh authentication. Nothing at all. You are barking up the wrong tree. Obviously, this needs to be done with a long and random password, but, for example, having an emergency login password in a sealed envelope that has > 100 bits of entropy is perfectly fine.
I should also remark that you are calling for the removal of the _mechanism_ as the vulnerability is specifically for the mechanism being there but "disabled" in a slap-dash way. Removing the mechanism is a crazy thing to ask for.
Re: (Score:3)
The title seems kind of wrong (Score:5, Informative)
Re:The title seems kind of wrong (Score:5, Insightful)
Yeah, crypt() *should* return a NULL pointer, *not* some arbitrary string when there's a fault. Entirely musl's bug.
Re:The title seems kind of wrong (Score:5, Insightful)
For legacy reasons, Crypt() is not allowed to return a null pointer. Some old applications do not expect a null pointer and will crash. On error, it instead returns a string that starts with *. In GNU C the string starts with * and then has a partial, invalid hash. In Musl C it just has the *. Crypt() never returns * on success.
Check the man page.
Re:The title seems kind of wrong (Score:5, Informative)
Re: The title seems kind of wrong (Score:4, Informative)
In the man page I see:
RETURN VALUE
On success, a pointer to the hashed password is returned. On
error, NULL is returned.
Re: (Score:3)
Consider these two man pages:
Debian Linux 5 years ago: https://manpages.debian.org/bu... [debian.org]
Debian Linux now: https://manpages.debian.org/tr... [debian.org]
Re: (Score:2)
You have the order reversed. It used to say null on error. Now it says * on error if so configured (which by default it is).
Re:The title seems kind of wrong (Score:5, Funny)
Re: (Score:2)
That would actually be a good idea. Just crash instead of returning NULL.
Even if you "check" the result of malloc(), there isn't much you can do than immediately abort, without calling any function that may call malloc again (so no dprintf, warn, err, etc., no way to even print a proper error message that would help determine if that was caused by low memory or a bogus size argument).
Re: (Score:2)
If you want that behavior you can make a macro which does an assert() after the malloc. C is about giving you the power even if 99% of the time the error should be considered fatal.
Re: (Score:2)
No. assert() calls asprintf() [github.com] therefore malloc().
Is it really that hard to try to grasp what I was trying to say above, with than thing that "you can't even print a proper error message" without malloc?
Re: (Score:2)
The Linux kernel, ostensibly, follows the same philosophy of "you do not break userland" but in reality bugs happen all the time and this kernel philosophy actually doesn't help at all because Linux is the worst mainstream operating system for any kind of backward or forward compatibility--for some fucking reason you can't compile a static binary on most distros.
The Linux kernel is great for backwards compatibility. GNome is horrible.
IF you make a backwards incompatible change, you are giving millions of people extra work. Don't do that.
Re: (Score:3)
No, if you read the man page for crypt, a failed return is supposed to start with the "*" character while a successful run will not contain a * character anywhere. GNU libc returns a * followed by additional characters while musl C only returns the *. OpenSSH failed to check whether the crypt output started with *, signaling an error.
That's an OpenSSH bug.
Re:The title seems kind of wrong (Score:4, Insightful)
No, if you read the man page for crypt, a failed return is supposed to start with the "*" character while a successful run will not contain a * character anywhere.
Funny, the Linux man page [man7.org] for crypt says it returns NULL on error. Same with the Mac man page [apple.com].
Anybody who thought that returning a string on error was a good idea just because some badly written piece of code might crash should never be allowed to write software. Let it crash. Fix the bug in the other software. Working around one bug by creating a second bug is pretty much always a mistake unless it is targeted sufficiently to prevent the bug from causing further harm.
Re:The title seems kind of wrong (Score:5, Informative)
You're looking at an older copy of the crypt man page. Compare the two from current Debian and Debian from 5 years ago. Current Debian returns a string starting with "*" so that older applications fail closed (as explained in the man page).
https://manpages.debian.org/tr... [debian.org]
https://manpages.debian.org/bu... [debian.org]
Re: (Score:2)
You're looking at an older copy of the crypt man page. Compare the two from current Debian and Debian from 5 years ago. Current Debian returns a string starting with "*" so that older applications fail closed (as explained in the man page).
https://manpages.debian.org/tr... [debian.org] https://manpages.debian.org/bu... [debian.org]
You have those backwards. The 2017 man page says that there is an option for returning a string starting with "*", depending on how the library was configured. The 2018 man page says that it returns NULL on failure... because they realized eight years ago that a non-NULL return on failure was a mistake.
Re: (Score:2)
You are mistaken. That's a 2019 and a 2025 man page. The 2025 man page allows "*".
Re: (Score:3)
Re: (Score:2)
Yes. musl messed up string comparison. A beginner's mistake. This should not happen, it should be caught in review, and it should be caught in testing. A sign of gross incompetence on their part. Not that they are any worse than a lot of commercial software creation. They are probably still better than average quality in the software space.
Re: (Score:2)
BTW a lot of SV startups allow login with an empty password, despite a suite of unit tests. No one likes to write negative tests, so here we are.
Re: (Score:2)
musl does no string comparison there. The string comparison is done by openssh, in openssh code.
musl's "mistake" was (and FWIW, still is) that it was also returning the same "*" error string when the password was longer than some arbitrary limit (easy to trigger remotely), not just when the salt was garbage/unsupported (very unlikely to happen at all and impossible to trigger without root access to the server).
tl;dr; you're stupid and clueless
Re: (Score:2)
That's what the openssh people are saying. As usual, they're shamelessly using their "reputation" to shift blame
Go read more about the actual exploit -- openssh was actually accepting "*" as returned by crypt() as a valid hash, and they were comparing it against the "*' password-placeholder from system "users" like "games" or "daemon", which they were picking at random from /etc/shadow (search for "pick_salt()").
Re: (Score:2)
I don't read it that way. OpenSSH uses a shadow password selected from some other user to mitigate a timing attack, which is fine. But then it determined success based on whether the encrypted password was equal to the stored password. Note that the stored password was not the password of the user being logged in! If root has a * placeholder, you should NEVER be able to login as root, even if they match because you gave the placeholder account's correct password. This potentially turns a user exploit i
The way I read this is (Score:2)
The way I read this is that libraries like OpenSSH are now run through security checking AI models, but those models can't catch issues in parent libraries like musl. The kind of unexpected breakout from tunnel vision like https://xkcd.com/538/ [xkcd.com]
Do you read Sutter Cane? They are spreading.
Re: (Score:3)
To be fair, regular security testing would have nicely found this issue. Even somewhat competent fuzzing would have caught it. Or code review looking at border conditions. But apparently nobody bothered to do it.
Because LLMs are not priced realistically at this time and the LLM scammers are desperate to create the illusion their tools have far more worth than they actually have, they are burning money on these tests. Good on one hand, but a certificate of incompetence for the ones getting caught.
Use another character (Score:5, Interesting)
Linux accounts can be configured to prevent password logins by replacing their password hash with an asterisk (*) in the /etc/shadow file
I typically use "!" to prevent logins (and change the shell to one of the nologin alternatives, dependent on the exact Linux version).
Re: (Score:3)
Until someone uses "!" to signal some other error condition.
In-band error handling == bad.
Re: (Score:2)
I completely agree. Unless it is a standard flag that is specified and gets recognized directly. "May not hash to this value" is too indirect. It is cryptographically sound, but my intuition is this is "clever coding" which has no place in anything relevant to security.
Re: (Score:2)
The second step (changing the shell to block logins) is probably effective here as well. And you should always do this type of redundancy if possible, it gives you an additional level of safety or security. Also important because there may be many system accounts that have login blocked in this way. I am even more paranoid and set a long random password and forget it, because I find the "*"/"!" mechanism a bit suspicious. Looks my intuition was not wrong on that one.
Re: (Score:2)
Except "!" has an already defined different meaning to the library that reads the passwd database, so you're just creating a new problem.
"sshole" (Score:2)
Ah, I see they named it after Theo...
(I kid, I kid)
Theo is an avid cyclist. (Score:2)
Re: (Score:2)
Theo is an avid cyclist. He's an asshole, but I repeat myself.
/rimshot
In all seriousness, I appreciate his work and depend on it daily. But it's true he has a reputation.
Re: (Score:1)
"Asshole coders" come in two flavors: Damn good and not that good. Look at Drepper or Poettering for examples of the second group.
That Nasty Feeling (Score:3)
I have a nasty feeling that this bug will significantly impact Docker containers and many/most of them will not be updated anytime soon.
Root for all.
Re: (Score:2)
If you are putting SSH into a docker container, you are doing it VERY wrong.
Re: (Score:2)
I don't disagree, but there are other types of containers. Proxmox LXC Debian-based containers usually have ssh enabled by default, which is actually convenient.
Re: (Score:2)
likely appliance type things like routers smart devices that remove PAM for a simpler lighter linux.
Re: (Score:2)
Probably. The dark secret about all containers is that containers need almost full system administration. I expect a lot of container users never realized that and are unaware what a can of worms they put on their systems.
Why just OpenSSH? (Score:2)
Why wouldn't this work for the command prompt? Does PAM not use crypt? Or does it do something different when it sees an account with an asterisks as the password hash?
Re: (Score:3)
Re: (Score:2)
Good to see that somebody was careful. To be fair, the PAM developers are secure software people while the musl people are just regular developers. It makes a difference. And we need to get to a state where anybody touching anything security critical is actually in the secure software camp. Just "getting it to work" has run its course and cannot cut it anymore.
They want to pwn OpenSSH sooooo badly. (Score:4, Insightful)
Just goes to show you that being a conformist just gets you a bigger attack surface.
Re: (Score:1)
Just goes to show you that being a conformist just gets you a bigger attack surface.
Yes. And monocultures are a very bad idea because it gives attackers a lot more targets and hence motivations. Works for agriculture and IT security just the same, only that the attackers are more intelligent in IT security.
Re: (Score:2)
Oh, and look. Some blithering idiot moderated this down. Explains nicely why IT is not mature at all: Too many idiots with insufficient education in it.
Re: (Score:2)
Re: (Score:2)
Well, I thought these people at least understood the very basics of their job. Apparently I massively overestimated their competence level.
PAM must also be disable (Score:4, Informative)
Dropbear FTW (Score:2)
I just looked at a few musl-based hardware devices and network gear and they're all using dropbear due to the same constraints as needing musl.
Special case (Score:3)
First, "musl" is not the default c library in most distros. It is in some, make sure to check.
Second, disabling password login via "*" is something you may or may not do. What I do is set a long, random password and then not note it down. Same effect. The "* cannot hash to a legitimate password" idea has cryptographic merit, but I did find it somewhat suspicious. Funny coincidence my intuition was correct. I did not follow up on system accounts, so my intuition only did half of the job. Take care that distros may use this (Debian/Devuan does some system default accounts with "*" and with "!"), so the real "I am not affected" criteria may be musl or libc.
That said, on my Debian/Devuan installations all these accounts with "*" and "!" have /usr/sbin/nologin or /bin/false as shell, so a login should still not be possible. Does anybody know whether that is a reliable protection against this vulnerability?
Re: (Score:2)
That said, on my Debian/Devuan installations all these accounts with "*" and "!" have /usr/sbin/nologin or /bin/false as shell, so a login should still not be possible. Does anybody know whether that is a reliable protection against this vulnerability?
It should be easy enough to test. "sudo adduser a" then "ssh a@localhost." Carefully modify your passwd file to change the shell to /usr/sbin/nologin and try again. You should be logged out immediately.
/usr/sbin/nologin prevented logins.
I just tried it on Mint and
Re: (Score:2)
Re: (Score:2)
There's more to ssh than just interactive shell access, and a few passes with sftp to upload a new key that's bound to executing the shell is why you don't rely on a flawed interpretation. Don't guess when it comes to things in /etc/passwd and /etc/shadow. Go and read the docs carefully.
Re: (Score:2)
Fuck no. That "/usr/sbin/nologin as login shell" shit is so easy to bypass it isn't even funny
Re: (Score:2)
Great name (Score:2)
It leaves things wide open. Remote penetration without authentication.
Re: (Score:2)
Yes, it's a little better since it doesn't actually contain an obscenity, but it is clearly meant to imply one. That impacts the ability to inform people about it
So why C? (Score:2)
Seems like a rewrite of interfaces (and, everything), in Rust would be of large benefit.
How many more code-injection vectors do we tolerate? Especially, with automated fuzz testing (etc) of agentic connectomes.
Seems like the 20th century modality needs to go the way of DOS 1.0 EDLIN. It's bad for UI/UX, and is poor separation of concerns/security from the implementation/integration/maintenance side. :/
Re: (Score:2)