DISCLAIMER: This post is purely meant for educational purposes only. Do note that such attacks can be considered illegal. Do not try such an attack on any other person’s property without first obtaining his/her consent to do so. The author bears no responsibility of the actions taken by the reader(s).
What is a brute force attack?
A brute force attack is a cryptanalytic method of systematically submitting a number of passwords with the hope of eventually guessing the correct password. Put simply, it is a trial-and-error method of gaining access to a locked/protected/encrypted file, account, network, system etc. A brute force attack is useful, since it is mathematically guaranteed to guess the right password while systematically exhausting all possibilities. But the algorithm itself is not guaranteed to recognise when it has guessed the right password or encryption key, a concept which is explored in Dan Brown’s Digital Fortress. One such implementation of an ‘unbreakable encryption’ is one-time pad cryptography. Such encryptions are rendered unbreakable by brute force because of their mathematical properties. However, this post will be limited to discussing the basic concept of a brute force attack and a python implementation of the same.
How does it work?
A brute force attack is carried out by an algorithm that exhausts every single possibility of passwords with various character lengths. It can simply be constructed by first making a list of all possible characters and then using nested loops to generate guesses (with lengths equal to the number of loops, eg., an eight character password would require eight loops). Each guess can then be used to try and see if it works, and the errors in case of an incorrect password should be handled. Eventually, the right password will be guessed – it is just a matter of patience and time.
What are its disadvantages?
The main disadvantage of brute force attacks is the exponential increase in the time taken to guess the right password or an encryption key. To illustrate this, we shall make use of 64-bit and 128-bit encryption keys. Each bit can hold either a 0 or a 1 – giving us two possible values. Therefore, the total number of possible guesses for a 64-bit key is equal to 2^64. Assuming this takes one day to crack by a regular computer, a 128-bit key, in the worst case scenario, will take 2^64 times the time taken to correctly guess a 64-bit key, i.e., 2^64 days. Assuming that there are 94 characters that can be typed (including uppercase, lowercase, numeric and special characters), for a simple 8 character password, there are 94^8 possible guesses, which is approximately equal to 6.1 * 10^15, or over 6 quadrillion possibilities. An average computer could take years to guess such a relatively short password such as this. A medium sized botnet would take hours.
A simple python program demonstrating the working of a brute force attack
In this program, we will try to gain access to a 4-character numeric password protected zip file using python. We will need to import the builtin zipfile module for this.
#This is a program that attempts to brute force attack a 4-numeric character password/PIN protected zip file. #importing the required modules from zipfile import ZipFile import time #noting time when program starts starttime = time.time() #listing the characters to use numbers = list(map(str, '0123456789')) #variable that tells us if we've found the password and can be used to tell the program to end cracked = False #nested loop - 4 levels for a 4 number long PIN. Break statements tell the program to exit each successive loop if the password is found for n1 in numbers: if cracked == True: break for n2 in numbers: if cracked == True: break for n3 in numbers: if cracked == True: break for n4 in numbers: pin_guess = n1 + n2 + n3 + n4 #form a pin pin_guess_in_bytes = (bytes(pin_guess, 'utf-8')) #encode it in bytes; ZipFile.read function takes its password parameter as a bytes object with ZipFile('/Users/sureshp/Desktop/samplezip.zip', 'r') as zip: try: #tries accessing the file with the guessed password data = zip.read('Users/sureshp/Documents/Sample/Untitled.rtf', pwd=pin_guess_in_bytes) cracked = True #changes the variable value to true print(data.decode('utf-8')) except: #handles error in case of wrong password and continues the program continue if cracked == True: #prints the password and time taken and then breaks the loop, thereby ending the program print("PASSWORD FOUND:", pin_guess) print("TIME TAKEN:", time.time() - starttime, "seconds") break
There are 10^4 possibilities in the above example. The program stopped after 4567 tries as it found the correct password.
NOTE: You will have to change the filename parameters in the above code as per your own file paths. The text that will be displayed will be of your own making.
The time complexity for a brute force attack in the worst case scenario is O(n^m), where n represents the number of possible characters and m is the total number of characters in the password. The best case scenario yields a time complexity of O(1).
The github link for the program is: