Hide SSH traffic inside Privileged Session Management (PAM)

Photo by Tomas Martinez / Unsplash

A Privileged Access Management (PAM) solution for SSH centralizes access control, monitors and records sessions, filters commands and provides audit logs and reports. The aim is to reinforce security by creating an SSH bastion that actively controls and monitors connections to critical systems.


This article follows on from the TCP connection encapsulation workaround in SSH:

Bypassing TCP port forwarding in SSH: how to detect it?

But in the case of PAM, this is impossible. A PAM checks that the data passing through the SSH terminal really corresponds to a SSH stream. For example it checks that the data stream corresponds to character transfer. If you start exchanging binary data inside the SSH connexion, the PAM will quickly close the connection.

I say checks that the data stream corresponds to character transfer? A PAM does not necessarily prevent the opening of an interactive shell (it depends on its configuration), you can still edit a file or open a tmux session. There is a certain laxity in the flow of exchangeable character.

Binary to hexadecimal

Converting binary flow to hexadecimal flow

The goal: instead of passing a binary stream directly into the SSH terminal, we'd have to convert the binary stream into characters, then decode it on the way out. And vice versa in reverse.

The rest of this article will be based on an SSH connection using bash. I need two pipe programs to perform both types of conversion. One to convert stdin binary input to hexadecimal characters on stdout. One to convert stdin hexadecimal characters input to binary output on stdout.

Python just for testing purpose. The same code is available in Golang with compiled executable:

GitHub - arfevrier/hexadecimal-binary: Unbuffered hexadecimal encoder for shell command
Unbuffered hexadecimal encoder for shell command. Contribute to arfevrier/hexadecimal-binary development by creating an account on GitHub.

Usage:

$ echo -n "Hello world!" | ./hexadecimal-binary -mode encode
48656c6c6f20776f726c6421
$ echo -n "48656c6c6f20776f726c6421" | ./hexadecimal-binary -mode decode
Hello world!
$ echo -n "Hello world!" | ./hexadecimal-binary -mode encode | ./hexadecimal-binary -mode decode
Hello world!

Note:
It is not possible to use xxd command, because xxd input is buffered and wait a line feed/carriage return before printing the result.

Using both programs, you can convert any input binary stream into a sequence of characters.

Hide binary stream with character

Pass a binary stream through the SSH terminal by exchanging characters.

For example, let's imagine we want to communicate with a remote server using HTTP. Perhaps the bastion won't let us because we're exchanging binary content in the HTTP session.

$ ssh user@server@bastion "nc google.com 80"

If we add the pipe convertion, the SSH bastion server only see a flow of hexadecimal characters. It will not block the connection, as the character flow is correct.

$ hexadecimal-binary -mode encode | ssh user@server@bastion "hexadecimal-binary -mode decode | nc google.com 80 | hexadecimal-binary -mode encode" | hexadecimal-binary -mode decode
Host server
   User arnaud
   Hostname server.local
   Port 22
   ProxyCommand hexadecimal-binary -mode encode | ssh arnaud@bastion "hexadecimal-binary -mode decode | nc %host %port | hexadecimal-binary -mode encode" | hexadecimal-binary -mode decode

(Of course, you need to be able to transfer the hexadecimal-binary executable or Python equivalent to the destination server beforehand)

Then everything becomes possible:

  • We can switch from clear traffic to SSL traffic. The flow seen by the bastion still be characters.
  • Using OpenSSH and ProxyCommand it's possible to encapsulate an SSH connection to jump invisibly to some other server.

To conclude, we've seen how to pass a binary stream through the SSH terminal by exchanging characters. This shows once again that the possibilities offered by the SSH protocol are vast. When configuring a PAM, you'll need to make sure that the commands used to set up an installation of this type are properly monitored. And keep an eye on the rate of network data traffic passing through a connection.

Arnaud
me@arfevrier.fr
Rennes, France