Open source software security

Web Hacking Lesson 3 - Brute Force

30 November -0001
Justin C. Klein Keane
April 18, 2007

Brute Forcing

Note: If you haven't read Lesson 1 go check it out first for test application install instructions.

Brute forcing a web application is a method to bypass traditional authentication checks. Although brute forcing may seem like an attack that a PHP developer might not be able to mitigate, it is actually an important consideration when developing web applications.

The largest drawback to brute force attacks is that they are noisy, and they take a long time. Traditional brute force attacks attempt to guess username and password combinations for services like FTP, SSH, or other authenticated protocols. Fortunately, these services were designed with this sort of attack in mind, and in general they log failed authentication attempts. This means that if someone tries to guess a password a log entry is created for every failed attempt, which leaves quite a trail of evidence behind. Web applications, on the other hand, rarely log failed login attempts. A traditional web server will log error requests (things like 404 errors) and PHP or other application level errors, but a failed login attempt, in most cases, is handled by the application and the web server never becomes aware that there was a failure. Thus, unless a developer specifically codes a function to log failed attempts, there rarely is any evidence that anyone has failed the login. The only evidence will be lots of hits on the page that handles the authentication. However, if this handler is built into a regular, content displaying page, there may be little evidence even in the access logs that an attack is taking place.

Fortunately for most web developers there are very few automated web (form) based brute force tools. There are tools for brute forcing web server based authentication (IIS or Apache authentication for instance). However, for our simple test application, the application itself is using a form with POST variables to perform the authentication (and is keeping absolutely no logging).

The fact that no easily packaged 'script kiddie' tools exist to attack the test application may make it seem more secure. However, it is quite easy to write a brute force attack script by hand, given a little programming knowledge. While an attack of this sort might take some skill, and a little time, it would most likely go completely undetected. Take the simple Perl script I've written below:

#!C:\Perl

use LWP;

# Create a user agent object
my $browser = LWP::UserAgent->new;

my @password_guesses = qw(admin access advice beekeeper password test zeebra);

foreach $password (@password_guesses) {
 $response =  $browser->post( 'http://localhost/madirish/login.php',
    [ 'username' => 'admin',
      'password' => $password,
    ]
  )->as_string;
  
 if ( $response  !~ m/Sorry/) {
    print "Successful log in as 'admin' with password '$password'\n";
 }
}

Now, to run this script you'll have to have Perl, and the Perl LWP package installed (which is standard in many distributions). Perl is available for Windows and Linux and is a wonderfully handy language to have at hand. Using this simple script I can successfully brute force the test application if I have the right password in my list of 'password_guesses' and the correct username. You could even modify the script so that it automatically generated a password, but downloading dictionary files off the internet is rather trivial. I'm leaving this script in a relatively unfinished state on purpose (so it can't easily be used to attack legitimate web sites) but with a little knowledge of Perl it would be easy to extend it into a full blown brute force attack tool.

If you have perl installed and you copy this script into a file and save it as brute_forcer.pl then run it at a command prompt with:

perl brute_forcer.pl

It will correctly guess the admin password of the test application. Be sure to make the script executable if you're on Linux and verify that the path is correct in the script to the actual login page.

Preventing Brute Force

Unfortunately there is no way to prevent a brute force attack against your site. A brute force attack uses legitimate services that you want to provide in an illegitimate way. The best way to defend yourself is to implement mitigation steps. The first (and most obvious) way to thwart a brute force attack is to choose (and enforce users choice of) difficult, complex passwords. It is also advisable to log failed login attempts.

The best prevention is to lock out accounts after a certain number of failed login attempts. This strategy is dangerous though, because an attacker could cause a denial of service against your web application by purposely failing logins for known accounts.

A better way to prevent this attack is to block IP addresses that try too many logins within a certain period of time. You may still have problems with users getting locked out of their accounts because they failed their login too many times, but at least you can't have a remote attacker lock you out of your own account.

Ultimately brute force attacks are a headache, and something you need to keep an eye on. Unfortunately, far too many developers simply ignore brute force attacks, neither implementing steps to mitigate them nor even audit trails to identify them. This leads to a dangerous environment where attackers are given carte blanch to attack web applications and raises the chances of applications falling victim to brute force attacks.