Page cover

Brute Force Automation (Python + Selenium)

Sometimes, the typical brute force attack, where you capture HTTP requests and repeat them using tools like Burp Suite Intruder, isn't possible. πŸ€” Whether it's due to traffic interception restrictions, session handling challenges, or any other obstacles, the traditional approach doesn't always work.

This is where Python + Selenium comes into playπŸš€. In this post, I'll show you how I automate this technique in a unique way, using Selenium to interact with forms and pages, and combining it with Python to capture and process the responses we get.

Part One: Selenium

Why Sleneium?

When I started in the world of penetration testing, one of the attacks I carried out the most was related to brute force. Whether it was finding valid credentials or automating information extraction, Burp Suite's Intruder became one of my top tools every day. As reports piled up and mitigation measures appeared, I began to wonder: are these attacks really being mitigated, or are there still other ways to carry out brute force attacks? Sometimes, we noticed that the data in the requests was encrypted, making it hard to intercept, modify, and repeat. That's when Selenium came into my hands, along with a few other tools with similar goals.

Selenium is a testing automation tool that lets you simulate interactions with web applications, just like you would when browsing manually. Commonly used in QA, it allows developers and testers to run automated tests to validate how their applications behave. And it's this ability to control web browsers that makes it a fun option to explore for brute force attacks. Instead of the usual intercepting and modifying traffic, we focus on simulating how a bunch of people would interact with the site!

circle-info

In this article, I won't focus on explaining how to install the tool, but rather on its practical useβ€”so feel free to look up the installation process elsewhere!

Selenium 101

To dive into automating a brute force attack, we first need to understand the fundamental concepts and commands of Selenium. Familiarizing ourselves with these basics will help us effectively navigate and interact with web applications for our security tests.

Using Drivers

The primary unit of Selenium is the driver, which serves as a bridge between our code and the browser. Each browser has its own specific driver (like ChromeDriver for Chrome or GeckoDriver for Firefox) that allows Selenium to control it.

circle-exclamation

Here's a basic example of how to start a driver in Python:

# Import the webdriver module
from selenium import webdriver

# Start the Chrome driver
driver = webdriver.Chrome()

Once the driver is initiated, we can use it to navigate to the desired website:

I particularly prefer to handle the URL in a variable, as this makes it easier to modify and reference later on.

Finding Elements

Once the driver has been initiated and we have navigated to the site, we can interact with page elements. Selenium allows us to find elements in various ways:

Once we have located an element, we can perform various actions:

For dropdown menus, you can use the Select class:

While there are many more ways to interact with elements, these basic commands will be helpful to get you started. Once you're comfortable with these, you can explore additional methods to enhance your automation skills.

Selenium Beyond Basics

To dive into automating brute force attacks, there are a few advanced concepts we need to grasp. We'll cover how to manage wait times, capture responses from elements, and add delays between interactions. These techniques are key to making our tests more effective.

Implicit and Explicit Waits

Managing wait times is crucial to ensure that elements are available before interacting with them. In Selenium, we can utilize two types of waits:

Implicit Waits: These are set globally and specify a maximum time the WebDriver will wait to find an element.

Explicit Waits: These are used to wait for specific conditions on elements. This is useful when we know an element may take some time to appear.

To ensure that your script continues only once the desired element is available, helping to avoid "element not found" errors, it's better to use explicit waits. They allow you to wait for specific conditions, making your tests more reliable and less prone to timing issues.

Part Two: Brute Force Automation

Now that we understand the basics of Selenium, let’s get our hands dirty and conduct a brute force attack in a controlled testing environment! For this proof of concept (PoC), we will be using the login feature of Juice Shop.

Identifying the Login Elements

The first step will be to identify all the elements we need to interact with. In this PoC, since we want to simulate the behavior of a user logging in, we will need to fill in the email and password fields, as well as click the "Log in" button.

Juice Shop login interface: elements to be automated with Selenium

Particularly, what hasn't failed me in this type of testing is using the XPath of the elements to identify and reference them with Selenium. To do this, we will use the browser's "Inspect" tool to access these values.

Accessing the 'Inspect' tool in the browser: key to identifying elements

Once inside the inspect tool, we will locate the element we want to interact with, such as the email field, and in the options, we will look for the option to copy the XPath.

Locating an element in the 'Inspect' tool and copying its XPath

It's important to save these values so we can use them later in our code:

Preparing the Test Set

Before we dive into the code itself, let's prepare the dataset we will use in this PoC. There are multiple ways to load data, and you can choose the one that suits you best. Since this exercise is not intended to delve into programming issues, we will simply load the email and password values from a .txt file, where each credential will be on a separate line and both values will be separated by a comma.

credentials.txt

triangle-exclamation

The Code πŸ–₯️

Now, let's get to the action. The first thing we will do is start our driver. In this PoC, we will be using Chrome as the browser. Additionally, we will make some configurations to prevent warning messages from cluttering the console output and affecting the evidence.

This code snippet shows how to configure the Chrome driver for use in this PoC, suppressing warning messages and errors in the console:

Next, we will configure the necessary variables, such as our target (URL) and the credentials file.

I like to print information about the test to be performed, such as the target, date, time of execution, type of driver, and the version of Selenium in use. This is useful to ensure our evidence is as complete as possible. To achieve this, we will create a function that prints the information of the test being executed:

Before starting the simulation, we will load the test data that we will use in each interaction we simulate. Remember that, in this case, we will be using a .txt file called credentials.txt

Now, we will create a function to interact with the browser elements. To do this, we will use the xPath values we previously determined and interact with the corresponding elements. A useful approach here will be to use explicit waits, which will ensure the element is present in the browser before interacting with i:

In this case, we are using explicit waits to ensure that the elements are fully loaded and ready to be interacted with before proceeding. We set a maximum wait time of 10 seconds for each element to appear or become clickable. This ensures that the automation script does not proceed until the required elements are present and interactable, helping to avoid errors due to timing issues.

There are various ways to approach the next stage, which involves analyzing the system's response to the different credentials we will be testing. Evaluating error messages, identifying newly loaded elements, redirects, and more are just a few of the available options.

We will particularly focus on the redirection. Once we click the login button, we will look for the element associated with the error message (using its xPath). If this element is present, it indicates that the credentials are incorrect. On the other hand, if we cannot locate the element, it will mean that we have successfully logged in and have been redirected.

circle-exclamation

This would result in the following final script:

Running the Code πŸš€

This would be the final result when running this PoC. Since it is a controlled test environment, we have included valid credentials in the dataset to demonstrate when valid credentials are detected.

Script Output: Brute Force Results with Selenium

Conclusions

The use of Selenium in penetration testing is a valuable tool when more "traditional" methods are unavailable. The ability to simulate human interactions in the browser allows us to identify vulnerabilities that depend on these actions. Additionally, its automation can save time in the process. However, like everything in life, it has its drawbacks, such as slower performance compared to more traditional tools and the need to maintain scripts in response to changes in the user interface. Overall, as a pentester, Selenium should be part of your toolkit, but it should always be complemented with other techniques to achieve a comprehensive and effective approach that allows you to explore all the dimensions of what you are evaluating

Last updated