Exploiting a NodeJS SSH Server with CVE-2018-10933

Oct 31, 2018


In recent weeks CVE-2018-10933 has created a great deal of excitement online. This is a vulnerability in ‘libssh’ before versions 0.7.6 and 0.8.4 which allows an attacker to circumvent SSH authentication. 'libssh' is a library written in C implementing the Secure Shell (SSH) protocol and can be used to engage client and server applications. This vulnerability allows an attacker on the network to gain SSH access without supplying any authentication details.

The public advisory issued by ‘libssh’ can be found here.

The full range of vulnerable products using libssh was still unclear when writing, however as a proof of concept the vulnerable and deprecated NodeJS SSH server has been used in this blog.

The Vulnerability

Vulnerable Software: libssh <0.7.6 and libssh <0.8.4

The vulnerability is quite simple conceptually. A server using the above versions of ‘libssh’ expect a ‘SSH2_MSG_USERAUTH_REQUEST’ message during authentication.

This bug occurs when we supply a message of ‘SSH2_MSG_USERAUTH_SUCCESS’ in place of the above, after which the server will grant us access without requiring any credentials.

image diagram

Surprisingly, no one has dubbed this issue ‘Open Sesame’.

Lab Setup

npm, the package manager for NodeJS contains a vulnerable SSH library which uses the affected libraries. This lab will be setup in a scotch-box vagrant image.

This package can be installed by using a provisioning script such as the following (this should also work on any Debian base with Node+npm installed):

diagram1a

As part of our new install we already have a dummy SSH server that we can execute.

The ‘stdiopipe.js’ file contains a sample NodeJS SSH server, which will reply with a banner on successful authentication and spawning of a shell.

Here we can see how to run the server:

diagram
 ​
A successful banner after authenticating with the appropriate credentials:

diagram 2

That is all we need for our lab setup.

The Exploit

To exploit this issue, we can perform the following actions using the ‘paramiko’ Python library:

  1. Connect to the server (in this case 192.168.33.10 on port 333
  2. Send the ‘SSH2_MSG_USERAUTH_SUCCESS’ message to bypass authentication
  3. Invoke a shell in the established SSH channel
  4. Receive the banner sent when successfully authenticated with a shell to prove access.

    diagram2a

We have successfully achieved the authentication bypass and retrieve the banner, as shown below:

diagram 3

Remediation

‘libssh’ is a vulnerable component, rather than a vulnerable standalone piece of software in itself. As such, identification of software using vulnerable versions of ‘libssh’ should be prioritised and updated to the fixed versions.

I have never come across someone who required NodeJS to deploy an SSH server, however if you are one of those people downloading and using the deprecated npm ‘ssh’ library, you should migrate to an up to date and supported package which will provide greater confidence in the authentication supplied.

darkarts