Jump to content
Byte-ul

[PHP Series] Brute Force and Dictionary Attacks upon Forms

Recommended Posts

What is it?

  • A brute force attack is where all combinations of characters are used in an attempt to find a user's password. It is more formally known as an enumeration attack.
    A dictionary attack on the other hand is where words are used. It can be used in conjunction with a brute force attack to form a hybrid attack.

How do I prevent it?

  • There are a number of techniques we can implement into login pages to prevent such attacks, as shown below.
    Page Timing
    • Sessions are used to maintain state within our web applications over a number of HTTP request calls. We can make use of them for timing form submissions to ensure that our form is not spammed or vulnerable to bruteforce/dictionary attacks. The following shows how we can implement such as system in PHP:

<?php session_start(TRUE);

if(!isset($_SESSION['mintime'])) {
$_SESSION['mintime'] = array(0, time());
}

if(isset($_POST['submit'])) {
if($_POST['password'] && $_POST['username']) {
// form validation here

array_push($_SESSION['mintime'], time());
array_shift($_SESSION['mintime']);

if($_SESSION['mintime'][1] - $_SESSION['mintime'][0] < 2) { // minimum time (in seconds) between valid form submissions
// form submitted too quickly
}else{
// successful form submission
}
}else{
// incomplete form data
}
}
?>

<!DOCTYPE html>
<html>
<body>

<form method="POST">
Username: <input type="text" name="username" />
Password: <input autocomplete="off" type="password" name="password" value="" />
<input type="submit" name="submit" value="Login!" />
</form>

</body>
</html>


Upon first landing on the above page, a session variable called mintime is created. It holds two values (time of initial page load and time of form submission), and is responsible for keeping track of the time between form submissions. With each subsequent form submission, a new value of the current time is pushed to the end of the $_SESSION['mintime'] array and the old time is removed from the beginning. Using these two times, we can find the difference between them and check to see if it is greater than the minimum amount of time between valid form submissions (which is 2 seconds in the above example).
One thing to note with this method is to ensure that at least the password field does not have a prefilled value (a feature often offered by most modern-day browsers). This is because we need the end user to manually type in their password to ensure that they aren't able to immediately submit the form upon landing on the page (which would cause an invalid login). We do this by setting the password field using the value attribute, and by setting the (HTML5) autocomplete attribute to off.

reCAPTCHA

  • Recaptcha is becoming increasingly popular as a method to prevent bots from performing form submissions. For those of you who do not know what reCAPTCHA is, see
this web page for more information. For this example, we will be using Google's reCAPTCHA, where we only manipulate the form data submitted once the reCAPTCHA has been correctly solved.
First things first, you will need to sign up for Google's reCAPTCHA. Having done that, you will now have your public and private keys at hand to be used in the following example. The next thing to do is to download the library associated with PHP, which can be found here. This will need to be included in both the generation of the reCAPTCHA within the form you're looking to protect, and also within the validation logic of said form.
Here's what our form page may look like with Google's reCAPTCHA in place:

<?php

require_once 'recaptcha/recaptchalib.php';

if(isset($_POST['submit'])) {
$privatekey = 'private_key_here';
$resp = recaptcha_check_answer($privatekey,
$_SERVER['REMOTE_ADDR'],
$_POST['recaptcha_challenge_field'],
$_POST['recaptcha_response_field']);

if(!$resp->is_valid) {
// What happens when the CAPTCHA was entered incorrectly
die ('The reCAPTCHA wasn\'t entered correctly. Go back and try it again. (reCAPTCHA said: '.$resp->error.')');
}else{
// Your code here to handle a successful verification
}
}
?>
<!DOCTYPE html>
<html lang="en">
<body>

<form method="POST">
Username: <input type="text" name="username" /><br />
Password: <input type="password" name="password" /><br />

<?php
$publickey = 'public_key_here';
echo recaptcha_get_html($publickey);
?>

<input type="submit" name="submit" value="Log in" />
</form>

</body>
</html>


The PHP code at the top of the page is the validation part, where an error is output if the input for the reCAPTCHA fails validation. If all goes smoothly, then we can continue to add our own validatory code within the else statement. For our form, we only need to echo out the reCAPTCHA form with the corresponding public key as the parameter for the reCAPTCHA generation function, recaptcha_get_html().
That's about as basic as it gets to adding reCAPTCHA to a form. You can visit Google's documentation on using its reCAPTCHA with PHP and other languages here.

Lengthening Successful Form Submissions

  • The
usleep() function in PHP causes a script to pause for a time in microseconds (there are 1 million microseconds to a second). It can be used after a successful form submission to slow down the page ever so slightly so that real users won't notice its effect, but brute force/dictionary attacks will. Even setting the value of usleep() to 200000 microseconds (0.2 seconds) will greatly impede such attacks, rendering them useless. Here's a quick example usage:

<?php

if(isset($_POST['submit'])) {
if($_POST['password'] && $_POST['username']) {
// form validation here

usleep(200000);

// successful form submission
}else{
// incomplete form data
}
}


This method is more of a quick hack to prevent this type of attack, and it's one that I personally would not use because there are better alternatives (as discussed above).

The techniques above are common ways to mitigate such attacks. There are other techniques that were not discussed above which can be deployed, such as account locking based on a certain number of attempts per IP address or requiring an answer to a random, pre-computed question. Using a computationally-slow hashing algorithm can also be a somewhat effective measure - though alone it will still allow for abuse on your Web form (which is something we want to mitigate).

Credits: http://www.hackforums.net/showthread.php?tid=4238146

Edited by Byte-ul
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...