Summary

SSH’s ProxyCommand is a feature quite widely used to proxy ssh connections by allowing to specify custom commands to be used to connect to the server. Arguments to this directive may contain tokens like %h, %u which refer to hostname and username respectively.

When coming from untrusted sources, a hostname can be malicious and look something like `malicious-command` (backticks would allow a command to be executed in shell)

More info in docs which describe this feature in detail

Let’s review an example

Taking an example based on the docs

Host *.example.com
  ProxyCommand /usr/bin/nc -X connect -x 192.0.2.0:8080 %h %p

In this case, there is no sanitization of hostname and if %h contains a malicious hostname, it may allow command execution.

Can I haz PoC?

What good is all this without a PoC? So here we go! Once you have added the above example to your .ssh/config, try following which should pop a calculator on OS X.

git clone https://github.com/vin01/poc-proxycommand-vulnerable --recurse-submodules

Even if the ProxyCommand is being used with single quotes to sanitize arguments i.e. '%h', it is not sufficient since an attacker controlled hostname might itself contain a single quote and defeat quoting.

PoC 2:

git clone https://github.com/vin01/poc-proxycommand-vulnerable-v2 --recurse-submodules

Remediation

Update to:

Vulnerable usage out in the wild

CVEs and references

My sincere thanks to:

  • Kevin Roh @ Okta for brilliant triaging and impact assessment
  • Jakub Jelen @ libssh for timely follow up and communication
  • Damien Miller and others @ Openssh for patches and discussions
  • Maintainers @ Git for discussions to define a potential trust boundary between ssh and git

How to donate to OpenSSH/OpenBSD