22 - SSH

Network scan

nmap can be used to scan the network for SSH services:

nmap -v -p 22 -A -oA nmap_ssh <IP | RANGE | CIDR>

User enumeration (CVE-2018-15473)

The OpenSSH service for all versions < 7.7 are vulnerable to oracle username enumeration.

The Python script sshUsernameEnumExploit as well as the Metasploit module auxiliary/scanner/ssh/ssh_enumusers can be used to validate the presence of a system user:

# [--threads <THREADS>] - Default to 5. If more than 10 are used, the OpenSSH service often gets overwhelmed
# [--outputFile <OUTPUTFILE>] [--outputFormat <{list,json,csv}>]
sshUsernameEnumExploit.py [--port PORT]  (--username <USERNAME> | --userList <USERLIST>) <HOST>

msf> use auxiliary/scanner/ssh/ssh_enumusers

Supported authentication methods

Authentication methods overview

The following authentication methods are possible:

  • password authentication: simple request for a single password with no specific prompt.

  • keyboard interactive: more complex request for arbitrary number of pieces of information. Can be hooked to two-factor (or multi-factor) authentications (PAM, Kerberos, etc.).

  • public key authentication: clients must provide a public key in the list of allowed keys on the server and encrypts a certain data packet using the private key. The public key authentication method is the only method that both client and server software are required to implement.

  • host-based authentication: host-based authentication is used to restrict client access only to certain hosts. This method is similar to public key authentication; however, the server additionally maintains a list of hosts mapped to their public keys and will only accept connection with the keys from the pre recorded host.

Supported authentication methods enumeration

A verbose connection attempt will display the authentication methods supported by the server (under debug1: Authentications that can continue:):

ssh -vvv <HOST>

The authentication methods supported by given SSH servers can also be enumerated more automatically using the nmap's ssh-auth-methods NSE script:

nmap -v -Pn -sT -p 22 -sV --script ssh-auth-methods --script-args="ssh.user=<root | USERNAME>" [-iL <INPUT_FILE> | <IP | RANGE | CIDR>]

Legacy DSA public key authentication

To connect to a server using DSA keys with a modern OpenSSH client, the PubkeyAcceptedKeyTypes +ssh-dss option must be added to the client config:

echo 'PubkeyAcceptedKeyTypes +ssh-dss' > ~/.ssh/config

If the client is not correctly configured, the following debug error message will be returned during the authentication process:

debug1: Skipping ssh-dss key ... - not in PubkeyAcceptedKeyTypes

Authentication brute force

Password & keyboard interactive authentication

The patator multi-purpose brute-forcer or the auxiliary/scanner/ssh/ssh_login metasploit module can be used to brute force credentials through the password and keyboard interactive authentication methods:

# auth_type: auth type to use <password|keyboard-interactive>
patator ssh_login host=<HOST> user=<USERNAME> password=<PASSWORD> -x ignore:mesg='Authentication failed.'
patator ssh_login host=<HOST> user=FILE0 password=FILE1 0=<WORDLIST_USER> 1=<WORDLIST_PASSWORD> -x ignore:mesg='Authentication failed.'

msf> auxiliary/scanner/ssh/ssh_login

publickey authentication spraying

The Metasploit's auxiliary/scanner/ssh/ssh_login_pubkey module and the Python script crowbar can be used to brute force SSH keys.

While an exhaustive attack is not possible, the key based brute force can be used for lateral movement once a private key could be compromised.

msf5 > use auxiliary/scanner/ssh/ssh_login_pubkey

python crowbar.py -b sshkey (-u <USERNAME> | -U USERNAME_FILE) -k <KEY_FILE | KEY_FOLDER> -s <CIDR>

A repository of static authorized SSH keys "hardcoded" into software and hardware products is available in the ssh-badkeys GitHub repository.

Known vulnerabilities

OpenSSL Predictable PRNG (CVE-2008-0166)

Due to a default of implementation of the seeding process in the OpenSSL package, all SSL and SSH keys generated on Debian-based systems (Ubuntu, Kubuntu, etc) between September 2006 and May 13th, 2008 are cryptographically weak.

All possible combination of public / private RSA (2048 and 4096 bits) and DSA (1024 bits) keys can be downloaded here:

https://github.com/g0tmi1k/debian-ssh/tree/master/common_keys
https://github.com/g0tmi1k/debian-ssh/tree/master/uncommon_keys

To retrieve a private key if its public counterpart could somehow be extracted from the server (/root/.ssh/authorized_keys or /home/<USERNAME>/.ssh/authorized_keys through LFI or file system disclosure, etc.):

# Only take the base64 content of the public key in format PEM
grep -rl <KEY> <FOLDER_RSA|FOLDER_DSA>

SSH clients

[Windows] PuTTY

PuTTY is a simple SSH, as well as telnet, rlogin and serial, GUI client for Microsoft Windows, available as an installed program and a standalone binary.

[Linux] parallel-ssh

The parallel-ssh / pssh command-line utility can be used to execute operating system commands through ssh on multiple hosts. The utility will return for each host the return code of the provided command.

The option -x '-q -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o GlobalKnownHostsFile=/dev/null' can be provided to bypass the verification of the target host key and prevent the saving of the host key.

# apt install pssh

# -i: displays the standard output and standard error of each SSH execution. By default, the outputs are not displayed.
# --inline-stdout: displays (only) the standard output of each SSH execution.
# -o <OUTPUT_DIR>: outputs the standard output of each SSH execution in a dedicated file (format: [<USERNAME@>]<HOSTNAME | IP>[:<PORT>][.num]) in the specified folder.
# -A: prompts for the user password (once for all of the specified hosts). By default, a authentication through SSH keys will be conducted.
# -t <0 | NUMBER_SECONDS>: allowed execution timeout in seconds prevent timeout of the execution, which can be necessary for
parallel-ssh [-i | --inline-stdout] [-o <OUTPUT_DIR>] [-A] -l "<USERNAME>" [-h <HOSTFILE> | -H "<HOSTNAME | IP>[:<PORT>] [<HOSTNAME | IP>[:<PORT>]]"] <COMMAND>
parallel-ssh [-i | --inline-stdout] [-o <OUTPUT_DIR>] [-A] [-h <HOST_FILE> | -H "[<USERNAME>@]<HOSTNAME | IP>[:<PORT>] [[<USERNAME>@]<HOSTNAME | IP>[:<PORT>]]"] <COMMAND>

# Bypass host keys verification and prevents the saving of the hosts keys.
parallel-ssh -x '-q -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o GlobalKnownHostsFile=/dev/null' [...]

# Execute the specified with elevated rights through sudo using the provided password.
# The first option is more secure as it does not leave any trace of the password on either the local or remote host but operational problems may arise.
stty -echo; printf "sudo password: "; read PASS; stty echo; echo "${PASS}" | parallel-ssh [...] "sudo -S <COMMAND>"
parallel-ssh [...] "echo <SUDO_PASSWORD> | sudo -S <COMMAND>"

Last updated