Many of us have jobs in which we typically only use SSH to connect to servers that we trust and control. But that assumption is no more baked into the security model of SSH than it is into the security model of HTTPS. The argument that "you trusted this server enough to connect to it and download a file, therefore you clearly should trust it enough to permit it to execute arbitrary executables on your machine" is false in both cases.
Great point. Also, imagine that you control the server and you know that it was compromised. Surely you want to be able to download logs and other files from it for inspection without having your own machine compromised.
Uhm, nope: you want to shut it down and perform forensics on the disk. Once it's rooted, I wouldn't touch it with a barge pole.
1. Shut down the instance
2. Connect the storage as secondary storage on another (disconnected from the network) instance
3. Do forensics using your cloud provider's out-of-band management interface
4. Throw away that instance as soon as you're done
We trust the browser not to have bugs, the TLS protocol to remain secure against attack, every CA to not grant MITM power to a state actor, the TCP/IP stack not to be remotely exploitable. Much of the world downloads unsigned code and exectues it locally, whether it be a Go client, an interpreted library code dependency, or "curl | bash". Windows has warnings before you run unsigned code, but most people run it anyway.
We trust a lot of things, and maybe we shouldn't. The important thing, to me, is how informed I am about the trust I'm giving, and to whom, and what risks I'm willing to take.
I use scp infrequently and on machines that I control, so that's a level of risk I'm comfortable with. But if the bug had been in curl, my blood pressure might be slightly higher.
Unless you run your browser without an ad blocker
On the one hand, you have a real point. On the other, JavaScript running in my browser has significantly less power to do anything bad to me than arbitrary executable programs running directly in my OS do.
I think that depends on what you mean by "significantly less power". It's entirely possible to use Javascript to place malware (such as installing a binary executable) and do other assorted nastiness on a target machine. If the target machine is properly secured, it's still possible, it just requires more effort.
This is the primary reason why I do not allow Javascript to run on my machines by default. If I'm at a site that I trust and I have no alternative to using, and the JS in question is essential, then I'll allow just the specific piece of JS to run. Otherwise, it's not happening.
This sounds interesting. Can you kindly link an example for this technique?
Your best bet (not guaranteed) is reading the html as plain text, not rendering any images, etc.
Nicely put.
This feels like yet another variant of the same confusion we see around web browsing, with people saying "oh, if you don't want a virus don't go to sketchy sites". Agreeing to receive HTML or even run unfamiliar Javascript in a browser shouldn't be equated with trusting that website to run anything outside the sandbox, and in a world where ads on major sites are frequently resold through a half-dozen shoddy networks it's an important distinction.
Even from a host you use all the time and where know the key hasn't changed?
Or use out-of-band access, e.g. a host-provided console, to connect once and extract the key.
For what it’s worth: The way to solve this is require the host key fingerprint as an argument to the ssh command, along with host and user. This would force people to look it up.
This is not a popular opinion, but I think it’s inescapable: SSH was not made for humans.
(This is purely a client issue, by the way. But at the end of the day: does that matter for anyone?)
(Edit: when this comes up people often mention key based auth. Unfortunately, that relies on nobody else having your public key. You can find mine anywhere, it used to be available through the GitHub api , even. It won’t let the attacker connect to the original server but they can definitely impersonate it. Perhaps get your key agent forwarded, and continue. Not great.)
Asymmetric key is not a solution to the problem of users blindly trusting hosts without checking the fingerprint. It’s a UI problem.
Every time I bring this up it gets shot down (e.g. now -3 votes), and every time I wait for someone to put forward an actual counter argument. Unfortunately, no luck.
SSH is broken and it needs fixing.
See it like this:
The bug is in the verification of the host, not the user. Eve can intercept a connection from Alice to Bob. It can "pretend" to be Bob, but it can't MITM (aka "proxy") because it won't be able to auth with Bob. However, auth depends on the server encrypting a message with Alice's public key, which everyone has ( https://github.com/torvalds.keys !), including Eve, so Alice will connect to Eve. Really this is nothing different from just connecting to a fresh host: you upload your public key to the remote ~/.ssh/authorized_keys somehow, and voila, right? How does your ssh client know that was the same server? The fingerprint. Did you check it? No.
Check out this article:
> The more well-discussed use of asymmetrical encryption with SSH comes from SSH key-based authentication. SSH key pairs can be used to authenticate a client to a server. The client creates a key pair and then uploads the public key to any remote server it wishes to access. This is placed in a file called authorized_keys within the ~/.ssh directory in the user account's home directory on the remote server.
> After the symmetrical encryption is established to secure communications between the server and client, the client must authenticate to be allowed access. The server can use the public key in this file to encrypt a challenge message to the client. If the client can prove that it was able to decrypt this message, it has demonstrated that it owns the associated private key. The server then can set up the environment for the client.
- https://www.digitalocean.com/community/tutorials/understandi...
As you can see, ssh public key auth authenticates the user, not the host. anyone could be that host.
Now: you as a human will quickly notice "where is my homedir? wait a second... this is not Bob—This is Eve!" the question is: quickly enough? If you were using scp: no, look at TFA. If you were connecting to github for the first time using git, perhaps using homebrew on a fresh machine: now you'll definitely never know. If you had set up your ssh key agent to forward keys to your "trusted" Bob host: serious trouble. There are loads of reasons why intercepting an SSH connection is a dramatic bug, even without being able to MITM it.
Or just try and turn it around: why do you think SSH prompts you to confirm the host key fingerprint, if it doesn't matter? For fun? They didn't add that as a joke.
Alas, few people understand this, as you so elegantly demonstrated :/
The host key fingerprint does matter. That's the host's public key. The host also has a private key. Without that private key, Bob can't pretend to be Eve.
You are correct that when connecting to Bob, if his public key doesn't match Eve's expected key, it will prompt the user to cancel the connection.
You argue: "It will only require the public key (which is public) to impersonate the server." The key piece here you are missing is that if Bob steals Eve's public key, he won't have a matching private key, and authentication will fail.
If you don't think the private keys are important, go edit them on your server, and see how SSH'ing in goes for you.
The attack is on Alice, who thinks she's connecting to Bob, but is actually connecting to Eve. This is on initial connect, and assuming Alice doesn't check the host fingerprint (which nobody does; that's the crux of my point).
This nomenclature is the convention when discussing cryptographic attacks: https://en.wikipedia.org/wiki/Alice_and_Bob
I'm going to stop discussing this in this thread, but feel free to contact me (info in profile). I promise to engage, in good faith, and if you do end up convincing me, I'll post an update here.
Best wishes.
You're fundamentally misunderstanding the argument about which key is being copied. It's Alice's public key that's copied. The fake server generates its own public and private keys and nobody notices that it doesn't match the real server. The user won't be "prompted to cancel" when this is their first time connecting.
authorized_hosts, as typically used, prevents an imposter from showing up later. It does absolutely nothing to prevent an imposter that's there from the start.
I've got a script sitting around here somewhere which does this... Not necessarily in a state that's easy to reuse, of course.
I did notice recently that cloud init has an option to hot a web hook when it is complete and they have options in there to add the host key to the POST. But I wonder how to make a web hook that would be immune to spoofing…
If after all that you receive a message an error from SSH that the host key identification changed, you didn't change this key yourself (or your team) and you still blindly ignore this issue (since it is not easy to bypass either, there is no flag, for example), this is not an UI issue and you're responsible for your actions.
I wrote about them some time back: https://ayesh.me/sshfp-verification
For servers without a domain pointed to it, I suppose you can still verify them by comparing the history key fingerprint by logging into said server with the console provided by server vendor.
The attack presumes your home directory is client side, and you use SCP to connect to any kind of server, whilst ~ is the client side open directory.
Thus, any server you might SCP to could write to your local home dir. In university, I did this with compute clusters, servers of my association and other servers.
This breaks the SCP security model because it means a server has covert access to your local working path. Whereas normally you know which files SCP touched, so you can verify they are as intended.
I just don’t understand the use case of scp’ing from an untrusted host.
Throw a Tectia server in the DMZ, fix the firewall, manage some keys (never change them) and you're good to go! Data at rest security via Zip or PGP for the ambitious.
Occasionally a big enough entity will mandate "everyone will use our data xfer spec" (and it's typically some gnarly XML-infested SOAPy animal). But there's a whole lot of automated business processes doing CSV-over-scp both intra- and inter-company.
Don't even get me started on FTP.
In which case, you leave your CSV-over-scp or CSV-over-FTP in place, and duct tape on another layer that handles the new data transfer spec. That way you can leave the 8 year old process itself alone and let it keep creaking away, silently chugging away as it slowly fades into the twilight of "important but forgotten" systems running on autopilot throughout the years.
It reminds me of how places like Rome still have sewers from the days of Ancient Rome in operation. Rather than replace them outright, they were just connected them to the newer sewer system to divert the waste to treatment plants instead of directly to water sources. And they'll keep on going, only being updated when absolutely necessary to warrant it.
Ideally your organization should keep updated (public) host keys somewhere, say on some https-protected website so you can double check yourself. How common is this?
(I mainly use ssh for interactive/tunneling use, but with a bit of bad luck the host key would change just in time for scp. BTW, don't rsync/unison use scp sometimes?)
Haven't yet encountered it in the wild though
We (rsync.net) are doing this in 2019. A little embarrassed we haven't done it already ...
Also, when I reinstall a server and keep the name, I preserve the keys from the original server.
I trust the cluster enough to give me those results. I don't trust it with write access to .bash_aliases . Thats why I did
scp file@host .
rather than scp *@host .You are SCPing to an untrusted machine, not from. Your client is trusted, the server you are connecting to is not.
Sometimes circumstances push you to connect to a server that is "semi-trusted" as described in the comments above.
What? Why would it even be an expectation that the host ought to be trusted? Would you say that about FTP, or HTTP or any other file transfer protocol? What's special about SCP?
And you may not even notice that the web server has been compromised until compromised PCs start acting up.
Should be fixed, but clearly not the worse vulnerability ever.
why you would want to fix this; client needs to verify the input it receives from server and not trust it's the right thing. malicious servers is just like how browsers get owned u know. it's not magic and very risky considering how many people have ssh / scp servers in their internal networks, which is just the kind of environment you can get away with a mitm attack on..
If you exclusively SCP to servers you control, this is admittedly a low priority issue.
However some companies use SCP extensively as a way to exchange data files (as an upgrade from using FTP, and out of frustration from dealing with implicit/explicit FTPS modes). Healthcare and finance come to mind for those use cases.
How did you arrive to the conclusion that the server has your home directory? The threat model: It's a server that you can authenticate to, retrieve files from there but otherwise you don't trust. It has nothing to do with your home directory. The PoC attack just shows the danger of invoking scp from the client's home directory.
That makes sense I suppose. I never scp files from untrusted hosts, nor can I think of a use case to do so, so it hadn’t really crossed my mind.
If I'm reading the OP right, whilst directory permissions can be modified, traversal is not possible, so it can't overwrite outside the directory you're writing to. But if you wrote to your home directly then your .bashrc could be modified ... and it sounds like other vulnerabilities allow the actual processing to be hidden (spoofed console output).
Seems like the sort of thing that could be used in a spear-fishing scenario.
I wonder if you could write a StackExchange answer with instructions to scp files from such-and-such server ...
This is not at all uncommon. Consider I need to send you files, either once or on a batch schedule.
You say, "give me your key, you can drop them on this server"
I feel safe since I am just writing files to your server, not expecting you are going to drop arbitrary code that will run next time I open my terminal.
But if I wanted to share files with you, I’d just put them on the web, unless we already have a relationship where you can ssh somewhere that I have access to.
In which case I assume we’re trusted or you’ve at least verified the host key.
If you "trust" any of these things is irrelevant, as that trust might be misplaced and the security model should keep you safe with compromised servers regardless.
I feel safe, because I think I'm going to cat a text file, not execute it.
Well but what if the server doesn't tell you it's compromised?
or, it means the otherwise previously trusted server has been compromised, and the sshd has been replaced with a malicious one.
From what I understand - if you scp any file from a remote server to your home directory, malicious remote server can copy anything else into your home directory without you knowing it, which can lead to remote code execution.
However, (1) the server needs to be malicious or compromised (or mitmd and you accept the new cert), (2) you need to copy into your home folder, not anywhere else, directory traversal is impossible
If you're accepting incorrect host keys, then you're completely breaking the ssh security model anyway.
I guess I don't understand how this is actually any worse than how ssh already worked?
Edit: To clarify, I understand why you’d want to fix this, for a good depth of defense. I’m just saying I don’t feel any urgency in fixing this.