timing-attack-checker is a simple PERL script that helps you check for timing attacks.
The most common form of timing attack I’ve noticed while pentesting is that the server may take longer to respond to a valid username than to an invalid username. This can be handy for bruteforcing a list of valid usernames. I’ll work through an example of such an attack below.
The script could also be used to test other types of timing attack. It should provide microsecond-resolution timing.
In its simplest form, you give it two commands you want it to record the execution time of. It will run those commands 100 times (by default), recording how long it takes.
timing-attack-check.pl 'login.pl -u knownuser -p x' 'login.pl -u notexist -p x'
The data is optionally saved in tab-delimited format for import into a spreadsheet. Some raw stats are also output to help you decide if you’ve found a timing attack or not.
Get the latest version from github
timing-attack-checker v1.0 http://pentestmonkey.net/tools/timing-attack-checker Usage: timing-attack-check.pl [ options ] 'cmd1' 'cmd2' ['cmd3' ...] options are: -n N Number of times to run the commands -o file File to write tab delimited data to Example: timing-attack-check.pl 'login.pl -u knownuser -p x' 'login.pl -u notexist -p x'
I set up an SSH server that only allowed logins using keys, not passwords. I wanted to know if the server would take longer to respond to a login attempt for a valid username than for an invalid username – presumably it does less work if the username is invalid. I load an SSH key into my ssh-agent so that the SSH client offers it to the server for each login attempt.
I used the following usernames for testing:
I had an ssh-agent running that had one key loaded. The key was not authorised to log into any account on the target system:
$ ssh-keygen -f key1 $ eval `ssh-agent` $ ssh-add key1
I ran the following command to make 40 login attempts for each:
$ timing-attack-checker.pl -o data.txt -n 40 'ssh x@host' 'ssh y@host' 'ssh z@host'
The script output the following:
[D] Running command: ssh x@host [D] Command took 0.464256 secs [D] Running command: ssh y@host [D] Command took 0.115495 secs [D] Running command: ssh z@host [D] Command took 0.128768 secs [D] Running command: ssh x@host [D] Command took 0.125885 secs [D] Running command: ssh y@host ... snip ... ================================================= Results for: ssh x@host Average time: 0.143035425 Minimum time: 0.10777 Maximum time: 0.464256 Standard deviation: 0.0608662980593068 (i.e. 68% of times within 1 sd, 95% within 2 sd) Was fastest on 3 out of 40 occassions (7.5% of the time) Was slowest on 10 out of 40 occassions (25% of the time) ================================================= Results for: ssh y@host Average time: 0.120723175 Minimum time: 0.095311 Maximum time: 0.206071 Standard deviation: 0.0171279751063684 (i.e. 68% of times within 1 sd, 95% within 2 sd) Was fastest on 36 out of 40 occassions (90% of the time) Was slowest on 3 out of 40 occassions (7.5% of the time) ================================================= Results for: ssh z@host Average time: 0.132942175 Minimum time: 0.114824 Maximum time: 0.154482 Standard deviation: 0.00611497853997666 (i.e. 68% of times within 1 sd, 95% within 2 sd) Was fastest on 1 out of 40 occassions (2.5% of the time) Was slowest on 27 out of 40 occassions (67.5% of the time) ================================================= [+] Saving tab-delimited data to data.txt
There are a lot of stats there. Let’s discuss each in turn an see if it leads us to believe that there’s a username enumeration issue:
So in conclusion, it seems that it would be possible to bruteforce a list of usernames that exist on the server tested. If anyone wants to look further into this issue, I’ve included details on my config at the end of this post.
More generally, you’ll probably want to run only two commands, not three or more. The option is there if you need it, though.
OS: Ubuntu 11.04
SSH Daemon: OpenSSH_5.8p1 (package: openssh-server 1:5.8p1-1ubuntu3)
Changes to default /etc/ssh/sshd_config:
PasswordAuthentication no Port 12345
CPU: AMD Athlon(tm) 64 X2 Dual Core Processor 5000+
Network: Wireless connection capable of around 3.5 MB/sec
Server was idle during testing.