Why using SSH agent-forwarding is a Bad Idea

Exploring how SSH agent-forwarding is Vulnerable

Harsha Koushik
Kernel Space
6 min readSep 28, 2020

--

Prerequisites:

  • Good Understanding of how SSH works and the type of authentication methods used in SSH.
  • SSH Agent Configuration and Usage

Introduction:

Basically SSH is used to connect to a remote host over a secure channel. Why did i specifically mention Secure Channel? Can that be done insecurely as well? Yeah, using Telnet. Telnet is one more protocol which is used to do the same job but all the commands you execute on the remote host are sent in clear text. With this intro given, let’s get started.

SSH —

SSH stands for Secure Shell. In simple words get Shell access of a Remote Host Securely. SSH uses port 22 by default and it can be changed if required.

SSH Syntax:

ssh -i <private key file> <username>@<hostname>
Example:
ssh -i internal_server.pem ubuntu@192.168.10.25

When is SSH Possible —SSH is possible if these three conditions are satisfied

  • Remote Host is directly reachable by your Host
  • Remote Host’s SSH port is Open
  • You have the credentials for SSH Remote Login — Private Key or [uname:passwd] or both in some cases.

Why is SSH Agent-Forwarding Needed then?

We are all good to go and get an SSH access if these conditions are satisfied. But in the real world, even if the Remote Host’s SSH port is open and you have the credentials to get in, you wouldn’t have the Network Clearance.

When i mean Network Clearance — you cannot access the Remote Server directly as they would be placed in an Internal Subnet which is not available to Public(Internet), which of course is a Best Security Practice.

Fig-1 | SSH through Bastion

So in almost any kind of infrastructure, a Server is placed in a Public Subnet which can be accessed through Internet which is known as Bastion Host sometimes also called as a Jump Host/Box. Bastion Host will have the Network Clearance to the Internal Servers. So the equation is simple —

To get into any of the Internal Servers, get into Bastion first and choose where to go from there.

Usually when we take a direct SSH access we will have the PEM file(Private Key ) on our Host Machine. But in this case, the Private Key used for Bastion Login is different from the Private Keys of Internal Server. So the Private Keys which will be used to login into Internal Servers must be living in the Bastion Host as we take access of Internal Servers from there.

So the practice of forwarding the Keys of Internal Servers to Bastion in advance is known as SSH Agent Forwarding.

Problem with SSH Agent Forwarding:

Basically when we forward our SSH Agent to Bastion, SSH-Agent creates a socket on the Bastion Host. So everyone who is able to connect to this Socket also has access to the Agent. This Agent is created in the /tmp directory.

Locating the Agent in Bastion

In this image, the agent doesn’t belong to the User called Mike. Someone else logged into Bastion with their Agent forwarded to Bastion. But now User Mike can see this Agent(Socket File) in /tmp/ directory.

Remember that the permissions on the Agent file will be set in such a way that, only User who forwarded the Agent can use it. But also remember that

Root User has access to everything in the System no matter what!

So in our case, User Mike has the permission to execute FIND command with Root Permissions using SUDO. He just searched for all the Sockets in the /tmp/ directory ending with SSH. Now he can see an agent, all he has to do is make this agent as his agent. That can be done like this —

Modify SSH_AUTH_SOCK ENV Variable

As mike has no idea about which keys are there in that Agent, he can blindly give some tries on some Internal Servers and manage to get into one like this

SSH into Internal Server

Remember that Mike has access to Bastion only because he works for the same organization. So he would definitely know the IP addresses of some Internal Servers. By any chance if he lands onto a Critical Server, simply forget your Weekend.

Don’t keep believing that only if a User has complete Root Permissions he can do something like this, Users with precise Sudo Capabilities can also do this.

One more way of thinking about this is — if your Bastion got compromised and the attacker gets ROOT access, the number of Servers he can get into using Agents on Bastion is left to your imagination.

Now comes the question — If Agent forwarding is a Bad Idea? Do you have an alternative Good Idea? And the answer is YES. Let’s see what can be the potential alternative for Agent-Forwarding which can do the same job pretty well without complicating anything in the existing Infrastructure.

SSH ProxyCommand:

Unlike Agent Forwarding this method is not going to Store our Keys on Bastion by creating an Agent or Socket. It connects to Bastion Server first and then executes a Proxy Command which in turn takes you into the Remote Internal Server without you having to execute SSH commands on Bastion.

Proxy Command can be used in a one-liner or can be specified in the ~/.ssh/config file.

One Liner:

ssh -i Internal_Server.pem -o "ProxyCommand ssh -W %h:%p -i Bastion_Key.pem mike@13.10.10.10" internal-user01@10.0.20.70

In Config File:

Host Internal_Server
IdentityFile Internal_Server.pem
HostName 10.0.20.70
User internal-user01
ProxyCommand ssh -i Bastion_Key.pem -W %h:%p mike@13.10.10.10

Note: Bastion Server IP is only for example and it’s not my Real Bastion’s IP

People often get confused by seeing the syntax of ProxyCommand. Just remember it like this — you connect to Remote Internal Server by connecting to Bastion Server first. Connection to Bastion Server happens in the background. All we can see is that we directly connect to the Remote Internal Server.

So in simple words, you connect to the Remote Internal Server through Bastion but, without actively interacting with Bastion and you are not going to Store any Keys on Bastion or open any sockets on it.

The -W option does all the magic by forwarding the standard I/O from the Client to Remote Host(%h), Port(%p) over the secure channel. All your commands are initiated from your Local Host and are forwarded to the Remote Internal Server through Bastion. So your Bastion has no control on your commands and keys.

Every Request Originates from your System and comes back to your System. Bastion acts as a forwarder here.

Conclusion:

Even today there are so many people out there who actively use SSH Agent Forwarding as a method to not only take access of some Internal Servers but also Production Servers which is not a Good Practice at all. If you are also from that group who’s still using Agent Forwarding, I urge you to change the access architecture.

SSH is one of the coolest Protocols in Network World. To know more about SSH and its options please refer — https://linux.die.net/man/1/ssh

Thank you for reading. You can connect with me on Linkedin . Happy to answer your queries.

--

--