SSH situation is insane(原声文稿)
Transcript of SSH安全现状离谱:一个基础协议如何坑遍全球服务器 (中文完整文稿)。
This bug is one that I truly cannot believe exists.
I was supposed to be filming a video on the 9 .8 CVE in the TCP IP stack of Linux, and then I literally saw this just scroll across my Twitter feed. Oh guys, I thought October was over.
I thought Cybersecurity Month was behind us and we can move on with all these CVEs, but this is an absolutely insane one that is a vulnerability in SSH itself.
Now the good thing is it's not an all SSH, it's just in a couple distributions, but there's still distributions of SSH to be used everywhere, so not a great place to be.
Obviously guys, in this video, I'm gonna show research with somebody else. I did not find this.
This is done by Ozgun Coltecun. Maybe I got that right. He is a worker, a researcher at Wakefield. So go show him some love.
I'm gonna be using this repo to go over the bug. Obviously they made it, so go check it out yourself.
They also did a very, very nice TLDR that I'm gonna try and use in this video because my kids are upstairs and they're making a lot of fucking noise. So, you know, I'm gonna be doing as best as I can.
Now, the news headline, which is exactly correct, combined flaws, let anyone into Alpine Linux and other distros by typing anything over 256 characters as a password, emergency fixes for open SSH and Musil libc, issued for millions of systems patched immediately.
Guys, when I went to my first black hat in 2013, I took some like bullshit how to hack into Linux and Windows course where they showed us like how to do a buffer overflow on like a Solaris box from like 2008, okay?
And what you did is at the login prompt, you typed in 294 As, and that got you a shell on the computer, okay? That was a box from 2008, 2009.
It is the year of our Lord of 2026, and this is still an issue. Now, I wanna be very clear.
What's really, really interesting about this bug is that despite it requiring you to put a lot of characters into a buffer, it is not a buffer overflow.
It is this really interesting issue where like the security boundaries and like the contracts of functions got so far apart from each other, and so confused over time, that people over time forgot what two functions did, and those functions like depend on each other. We'll go into what that means here in a minute.
Guys, real quick, every day it feels like a new crazy zero day falls out of the sky. So it's a question of when your network gets attacked, not if. So here's a TLDR, right?
When you log into a system over SSH, what is going on, it is comparing the given password, right? So you specify a password, there's nothing to do with public key authentication. You give it a password, right? And what it's going to do is it's going to run a variety of functions over this thing called Etsy Shadow. Okay, I don't have them because I'm on a fucking doctor image at she's shadow.
We'll notice here is there are some values that don't have any Hash okay, so you'll notice for example, this is root and there is a star here The star is very important But it means is that this account does not have a password this decision was made back in 1980 by Bill Joy for this account called Damon Which basically meant hey Damon does not have a password and because star is not a hash a hash a collision can never occur where no one can ever log in as an account. Perfect.
Now, when you're doing all this crypto, what's happening under the hood is using a library's crypt function, okay?
So crypt is a function in Moosl Lib C, if you're not aware of what Moosl Lib C is, Moosl Lib C is one of many implementations of Lib C. The one we know right now is GNU Lib C. That's a very common one. This is a different Lib C implementation that different systems use. It is a lightweight, fast, and simple, and free version that strives to be correct.
Okay, correct most of the time.
Okay, so in August of 2012, there is this issue where basically, originally the Muzzle Crypt function that was doing the cryptographic algorithm to check for your password hash, right?
So for example, we have $6, this $6 means you're doing a SHA 512 operation, and this is a hash of a SHA 512 password, and here is the salt, right? So it's algorithm, salt, and then the hash, okay?
Salt is like a value that you can catenate to a value before you hash it, okay? Basic crypto stuff.
For a while, this crypt function, if it fails, right, if there's an issue with doing the cryptography, if you gave it too much data, not enough data, for a long time, it would return the value null.
Well, a lot of programs are bad programs, they don't check the return value for, you know, their functions.
So instead of returning null in 2012, they decided, okay, we're going to return a character. And what is that character we're going to return? It's none other than the star.
Yes, it's the star again, the star is also the character that just happens to match with the value from Berkeley from 1980.
Not a big deal because there should be no cases where we're gonna actually compare these two values. Ah -ha -ha.
Okay, so there's no world where we compare this value to the value in Etsy Shadow because one is a star and the other is an error value, okay? So not a big deal there. Now for a long time, this wasn't really an issue, okay?
Until 2016 where there was discovered a timing attack in the way that Muzel Lib C did its crypto.
So for example, what if I wanted to figure out what user names were available on this system, right?
If I go an SSH into the box and I try to SSH into a username that does not exist like Bob, for example, that operation will immediately fail out when I do the password. I'll put the password in, it'll immediately come back. What's happening there is I'm doing a timing attack. There is no crypto operation in the background happening. I can use that timing to enumerate what accounts do exist on the box.
If I log in as Alice, for example, even if I don't know the password, I can time the difference between Alice and Bob and figure out that Bob does not exist because it came back quick, but Alice does exist because it took a second to run the crypto.
So to fix this in July of 2016, for accounts that either didn't have a password or didn't exist, what they would do is they would steal somebody else's hash.
They would temporarily borrow the hash and the salt of a different account and they would allow you to do the crypto operation on that salt and it's not really doing it for the account.
So for example, if Bob doesn't exist on this account or on this computer, what's gonna happen is the crypto backend is going to borrow Alice's salt and we're gonna do a password check of the given password on Alice's salt for a fake account.
What's happening here is they're trying to get rid of the timing attack that's happening inside of the crypto libraries. So let's say for example, I wanted to log in as the root user. The root user does not have a password. What's going to happen is it's going to allow me to log in.
It's It's going to do SHA 512.
It's going to borrow their hash and it's going to do the SHA 512 crypto algorithm on the input that I give it. All is well and good.
What could possibly go wrong here? Well, if you read the implementation of of crypt SHA 512 in Musil C.
If you'll notice, if the I value is greater than key max, it returns zero, okay?
Just sit and think about what I've said previously in this video and think about what can go wrong here.
If I is greater than key max return zero, key max is 256.
Okay, well, if SHA 512 crypt returns zero and the crypt function itself returns a star when there is an error and if the given hash for root is a star and we ultimately do a stir compare on the calculated hash a star and the given hash from the Etsy shadow file a star those are going to compare and be the same value that is going to pass as a password check what so the question is right like who is vulnerable to this bug well first of all this is a failure of implementation in the Moosel C library, okay?
So G lib C, the one like the library in C that is very common is not affected by this, right? You'll see the different builds and configurations of SSHD.
The only ones that are affected are Moosel C builds of open SSHD that don't have PAM modules, that don't have a portable authentication modules, that's what PAM stands for.
Also, if you don't have a shadow file and you have just your hash disorder and Etsy password, that also breaks it.
So there are some preconditions that have to be true for you to be vulnerable to this bug. First of all, you have to have password auth enabled. Now just to be clear, they are on by default.
You also have to have an SH server that is not using portable authentication modules.
So some SH servers by default do ship with PAM enabled. So if those are enabled, you are not vulnerable to this.
But unfortunately, the big kind of example here is that Alpine Linux, Alpine the Docker image ships in this configuration.
It has password logins on and it doesn't use PAM. It is vulnerable by default.
And literally like the only other part of the configuration you need to be true is there needs to be an account that is registered that has a star value as it's password in the Etsy shadow file or Etsy password if you don't have a shadow file.
And then another account with a real password that uses SHA 512, which is like the default now, $1 or $6.
If all of these are true, They literally all they have to do is put in a large number of a's like this many a's it's like two five seven to ten twenty four I think it's ten twenty four is the upper limit of SHD And that'll just drop you into a shell the issue with Alpine shell too is the Alpine user is the main user on Alpine This is also vulnerable and Alpine is a run as user or do as user so it's effectively pseudo It's effectively root looks like not great also for like tampering fear right important to highlight if you are on Debbie and Ubuntu Fedora, anything else libc going through a PAM using DropBear or OpenBSD, you're good.
It's literally just these couple of configurations granted, it's probably a large scale portion of the internet, but it's not a lot, I guess.
What makes this bug so interesting is just like, this isn't a memory corruption vulnerability, this isn't like, this is a logic bug, but it's not a logic bug, like they forgot to check for like the n or n plus one length of a string, right?
This is literally like, there are two different functions that have two different like contract agreements and over time they just drifted so far apart.
Like, oh, we're gonna use a star over here and like surely the star can never become a password hash.
And then over here it's like, okay, we're gonna have Crypt return a value that isn't null. Ah, what value won't really matter ever? Star, that'll be fine.
And then finally, okay, we're gonna let any user that either doesn't exist or doesn't have a password, use a crypto routine, and that crypto routine will fail above a certain length, and that failure will cascade into a star that is then the hash for the other users, like it's just, it's insane.
Now, my real question is like this, it's been vulnerable like this basically since they fixed this CVE, and then Alpine has been broken since 2021 because they changed the hash from a locked bang to a locked star because that broke Pam.
And so this has been a bug since 2016, it's 2026, it's been 10 years.
Their argument here is like wordless, haven't had 300 letter passwords, I guess, because literally all you would have to do is take a vulnerable version of this, log into an account that has this star as the password or as the hash, and then give it 300 days. Like we're talking 1992 levels of hacking, insane. A question you'd be asking, would Rust have fixed this?
Actually, no, maybe there's a world where the types or the enums or the result T or option T that they would use to do the error checking would prevent this, but from a pure use -after -free memory safety thing, this bug has nothing to do with that, so it's kind of interesting.
That's it, guys, if this was too fast or too quick, I'm sorry, I have my kids at home, so I'm trying to bang this video out without making too much noise or making you hear them.
If you like this style of video, do me a favor, hit that like button, hit subscribe, and then we'll see you in the next one.