The goal of this lab assignment to allow you to explore password security by developing Python code that performs a brute-force attack on a website.
For this assignment, you will be attacking the following website:
http://weasel.h4x0r.space:9999
As can be seen in the screenshots below, the website you are attack is relatively simple: it is a basic login form with a netid field and a passcode field.
Your goal is to write a Python function that will attack this website by attempting all possible numeric passcodes on the form (that is until it displays "Access Granted").
Note, this assignment is inspired by the FBI vs Apple encryption dispute discussed in class.
For this assignment, record your work in a Jupyter Notebook and upload it to the form below by 11:59 PM Wednesday, April 29.
To help you get started, we have provided you with a starter notebook, which you can download and then use to record your answers. To utilize the starter notebook, download it to wherever you are running Jupyter Notebook and then use the Jupyter Notebook interface to open the downloaded file.
The starter notebook is already formatted for all the various sections you need to fill out. Just look for the red instructions that indicates were you need to write text or the cyan comments that indicate where you need to write code.
The first activity is to write the attack
function:
def attack(url=URL, netid=NETID, length=LENGTH):
''' Attempt to brute-force attack the passcode for the specified
netid and specified passcode length '''
To do this, you will need to implement the following pseudo-code:
for each passcode of specified length:
Attempt to login to website with passcode
Check if login was successful
If a passcode is found, print it out, otherwise inform the user that
None was found.
In addition to performing a brute-force attack on the website, you should display both the elapsed time and a progress bar as you attempt each passcode as shown in the video above.
To determine the elapsed time, you can first record a start_time
using
time.time and then later compute the elapsed_time
by computing the difference:
elapsed_time = time.time() - start_time
To display a progress bar, you can use the IntProgress widget as follows:
# Create Integer Progress Bar with maximum value of 10^length
progress = IntProgress(max=10**length)
# Display Integer Progress Bar
display(progress)
To update the progress bar, you can do the following:
# Update Integer Progress Bar
progress.value = passcode
progress.description = f'{elapsed_time:0.2f} s'
To generate a sequence of passcode candidates, we can simply keep a
counter and use the str.zfill method to pad it with 0
's:
# Pad passcode with 0's
passcode = str(passcode).zfill(length)
To make a login attempt, you can use the requests.get method with a
params
argument.
# Attempt to login
params = {'netid': netid, 'passcode': passcode}
response = requests.get(url, params=params)
To check the contents of the response, we can search response.text
.
Once you have a working attack
function, use it to crack the passcodes
associated with your netid
:
>>> attack(netid='dmcdomer2', length=2) # Passcode of length 2
>>> attack(netid='dmcdomer3', length=3) # Passcode of length 3
>>> attack() # Default netid and length 4
Note, you should attempt passcodes of length 2
, 3
, and 4
For
passcodes of length 2
the netid
has a suffix of 2
as demonstrated
above. Only passcodes of length 4
have no additional suffix.
After attacking the passcodes of various lengths above, respond to the following reflection questions:
Describe how your attack
function works. How did it generate the
sequence of candidate passcodes and how did it check if the passcode
succeeded?
From this experience, what is the impact of passcode length on the security of a system?
Besides modifying the characteristics of the passcode, what else could a website do to prevent or mitigate brute-force attacks?
Once you have completed your lab, submit your Jupyter Notebook using the form: