I would be surprised that it could be that simple. Doesn’t the agent file has permissions like 0400 on the socket or similar protection?
OFC root could still use it, but that would at least cover your ass on shared remote boxes.
edit: answering my own question, from ssh-agent(1):
A UNIX-domain socket is created and the name of this socket is stored in the SSH_AUTH_SOCK environment variable. The socket is made accessible only to the current user. This method is easily abused by root or another instance of the same user.
Similar to JordiGH I know about the dangers of agent forwarding, but how exactly am I supposed to do the work I need to do on remote machines without it? Namely, I need to be able to e.g. git clone private repos using the creds on my laptop when I’m on a remote host. What other solution is there?
That’s a use case I haven’t hit, personally. You could invoke ssh-add with the -c flag so that ssh asks for confirmation before the key is used. On macOS, you’ll probably need something like theseal/ssh-askpass for the prompting to work.
This is actually only of limited use. The attacker waits for you to attempt a connection, then uses that opportunity to have your agent auth their connection. Then, oops, network interruption and you disconnect.
I always found the GPG setup too much of a faff. Using PKCS#11 with OpenSSH directly is much easier. I wrote up a howto (mostly for my own sanity): https://github.com/jamesog/yubikey-ssh
You can’t do that without SSH agent forwarding, but there are other options and remediations:
You can clone locally and scp it to the remote host, or you can turn on SSH agent forwarding only for a very brief period of time while the clone is happening, then log out immediately after it completes and reconnect without forwarding. You should not do forwarding by default.
Edit: upon further reflection, turning on agent forwarding for a short amount of time isn’t that much better than having it on regularly since the compromised host can be set up to watch for incoming connections and automatically hijack your agent as soon as you connect so I don’t recommend that.
In some cases it can be worthwhile to generate key material on the remote host itself, then authorise that material to pull the repo you need. GitHub can do this with, I think, “deploy keys” – and if you have gitosis, or whatever, you can obviously do whatever you like.
No. That lets you login to a third machine via a second machine, but not from the second machine.
You are on apple. You login to banana, a public host. You want to access carrot, a private host reachable from banana. Proxy lets apple login and access carrot. But a shell on banana can’t connect to carrot. Forward lets banana access carrot.
If, for example, you want to transfer a file via sftp from carrot to banana, your choices are agent forwarding and a direct transfer, or a proxy and downloading to apple and uploading back to banana.
You could also use SSH TCP forwarding on the apple-banana connection to make it so that you could use apple as a ProxyJump host from banana. So your connection would go banana->apple->banana->carrot. But that’s pretty convoluted, and is basically just an optimization of the “download to apple and upload back to banana” plan.
Thanks for the writeup. I saw the same issue, and wondered what the issue was. But since I only used it for computers that are in my direct control (ie. at home) it shouldn’t be too much of an issue.
I suspect it has similar issues. From what I recall, at least under some conditions you’d end up getting a ticket on the remote host which is often stored as a /tmp file, and which can be used for some number of minutes or hours for at least some things you’d be authorised to do yourself.
I’ve known about the dangers of this for a long time, but how exactly do you exploit this? Where do I read my coworkers’ private keys on our bastion?
I don’t think you can steal keys using this method (and the man page agrees).
That said, agent forwarding creates a unix domain socket on the bastion at
/tmp/ssh-$(RANDOM_STRING)/agent.$(RANDOM_INT)
so you can just:find the socket within it:
piggyback on the connection:
This shouldn’t have to be stated, but I feel the need to cover my ass: only do this on machines you own.
$(RANDOM_STRING)
comes from mkdtemp(3), but$(RANDOM_INT)
is in fact the SSH agent’s parent PID.http://man.openbsd.org/ssh-agent#FILES
I would be surprised that it could be that simple. Doesn’t the agent file has permissions like 0400 on the socket or similar protection? OFC root could still use it, but that would at least cover your ass on shared remote boxes.
edit: answering my own question, from
ssh-agent(1)
:The premise is that the jump box is compromised.
Similar to JordiGH I know about the dangers of agent forwarding, but how exactly am I supposed to do the work I need to do on remote machines without it? Namely, I need to be able to e.g. git clone private repos using the creds on my laptop when I’m on a remote host. What other solution is there?
Use more different keys. The key to run git clone should not be the key to become root on the database server.
That’s a use case I haven’t hit, personally. You could invoke
ssh-add
with the-c
flag so that ssh asks for confirmation before the key is used. On macOS, you’ll probably need something like theseal/ssh-askpass for the prompting to work.Or use gpg-agent with a yubikey. With tap confirmation enabled on the yubikey :)
This is actually only of limited use. The attacker waits for you to attempt a connection, then uses that opportunity to have your agent auth their connection. Then, oops, network interruption and you disconnect.
I always found the GPG setup too much of a faff. Using PKCS#11 with OpenSSH directly is much easier. I wrote up a howto (mostly for my own sanity): https://github.com/jamesog/yubikey-ssh
You can’t do that without SSH agent forwarding, but there are other options and remediations:
You can clone locally and scp it to the remote host, or you can turn on SSH agent forwarding only for a very brief period of time while the clone is happening, then log out immediately after it completes and reconnect without forwarding. You should not do forwarding by default.
Edit: upon further reflection, turning on agent forwarding for a short amount of time isn’t that much better than having it on regularly since the compromised host can be set up to watch for incoming connections and automatically hijack your agent as soon as you connect so I don’t recommend that.
In some cases it can be worthwhile to generate key material on the remote host itself, then authorise that material to pull the repo you need. GitHub can do this with, I think, “deploy keys” – and if you have gitosis, or whatever, you can obviously do whatever you like.
is
ProxyJump
enough?No. That lets you login to a third machine via a second machine, but not from the second machine.
You are on apple. You login to banana, a public host. You want to access carrot, a private host reachable from banana. Proxy lets apple login and access carrot. But a shell on banana can’t connect to carrot. Forward lets banana access carrot.
If, for example, you want to transfer a file via sftp from carrot to banana, your choices are agent forwarding and a direct transfer, or a proxy and downloading to apple and uploading back to banana.
You could also use SSH TCP forwarding on the apple-banana connection to make it so that you could use apple as a ProxyJump host from banana. So your connection would go banana->apple->banana->carrot. But that’s pretty convoluted, and is basically just an optimization of the “download to apple and upload back to banana” plan.
Separate keys for git authentication & login?
Thanks for the writeup. I saw the same issue, and wondered what the issue was. But since I only used it for computers that are in my direct control (ie. at home) it shouldn’t be too much of an issue.
can someone answer me whether Kerberos has the same issue?
Yes it does. It has other issues too like .k5passwd letting you list other users that can login to your account with THEIR credentials!
I suspect it has similar issues. From what I recall, at least under some conditions you’d end up getting a ticket on the remote host which is often stored as a /tmp file, and which can be used for some number of minutes or hours for at least some things you’d be authorised to do yourself.