Multithreaded password spray tool written on python using selenium packed as container image

 Hello Security Enthusiast,

Are you looking for a quick way to perform password audit thru spraying on a bunch of web applications part of your security assessment, then you have come to the right place. So i have written a small tool in python that can perform quick password spray attacks on different authentication methods (as of now its ntlm and form based authentication) across multiple targets and generate reports with enough details to help with the ongoing assessment.

Motivation & Inspiration

  • Part of my job is to run periodic assessments against large enterprises that have large number of applications deployed so i needed something to run across multiple targets at once and could generate detailed reports for each attempt. 
  • Another objective is to measure the effectiveness of monitoring controls in the environment so i needed a versatile solution that can be configured to different behaviour when needed, for example, perform a spray attack with delay between each attempts. Also it needed to generate detailed report to help from purple teaming prespective.

  • Enterprises often have different flavours of applications so the solution should be able to work in different flavours. For example, here it can perform password spray against NTLM based authentication as well as form based authentication.
  • Finally i needed a solution that can be quickly deployed in any environment with litte effort, so here the solution is packed as container image and has ablity to point at multiple targets with different flavours, all defined in single configuration file and finally can produce a single report per each run.


So python being so rich in libraries and good multithreading features was the obivious choice to build the tool. Since its largely web applcations i chose selenium with chromedriver to simulate any login attempts. Finally all these are packed into a docker container for easy deployments. The solution uses a single config file to define targets, user list, password list etc, its easy to deploy in any environment as per need.

Getting it

The tool is published on github here -  feel free to clone the repo or you can extend it

Building it

The docker image can be build with below command

docker build --tag moheshmohan/spray_tool:latest .

This should pull necessary requirements and build an image. (Mar 2, 2022) Please note i have not trimmed the image to include the exact requirements so you might be seeing some extra python libraries being pulled. I hope to optimize this in later revisions

If you don't want to build the image on your own, you can pull the latest one from dockerhub. Please note this is pushed using github actions so its automated and expect some stability issues. You can pull the latest image with the below command

docker pull moheshmohan/spray_tool:main

Running it

The tool can be run against multiple targets with each defined in a configuration file. A sample config file is already included on the repo to target Sample user names and passwords are also included. The below command can be used to run on the included configuration (config.ini)

docker run --rm -v $(pwd):/app --name spray.conta moheshmohan/spray_tool:latest -c config.ini

The above command allows the container to access files in the current directory so that you can pass configuration files and wordlists to the tool.

The argument -c followed by config file denotes the configuration used for the attack.

Configuring it

As of now the solution can perform password spray against NTLM over HTTP and standard form based authentication. Below are instructions on defining the configuration file to perform attacks against different targets.

General config

Sample general configuration is as follows

UserDelay = 1
passDelay = 2
userList = rand.txt
passList = pass.txt
Threads = 5

The default configuration defines some global settings which could be shared across each subsequent target entries. The are as follows

UserDelay : The delay in seconds between each usernames attempts. since the tool is multithreaded, the solution waits for specific seconds after each attempt of usernames

passDelay : The delay in seconds between each password attempts. In password spraying you can provide the tool with list of usernames and passwords it will take one password and iterate through the entire user list, once one iteration is completed the tool waits for the specified number in passDelay to initiate another run. combination of this and UserDelay can be used to evade monitoring controls to an extent.

userList & passList : Text files with line by line of users and passwords that needs to be attempted. These are global lists which can be overridden for individual targets subsequently in the config file

Threads : Number of concurrent threads 


Now lets talk about the configurations available for attacking NTLM over HTTP. A sample config looks like below

URL = 
Type = ntlm 
Domain = msg

URL : The target url to attempt password spray

Type : defines the type of attack, here it is ntlm 

Domain : The active directory domain name used for the spray attack.

userList & passList : Text files with line by line of users and passwords that needs to be attempted. These are global lists which can be overridden for individual targets subsequently in the config file

Form based authentication

The solution makes use of selenium to automate password spray attempts on any form based login. Since its chrome driver based to simulate browser consider the implications while configuring the number of concurrent threads.

A typical configuration for form based attempt is as follows

URL = 
TYPE = headless 
userList = rand.txt 
passList = pass.txt 
username_field = //*[@id="uid"] 
password_field = //*[@id="passw"] 
loginbtn_element = //*[@id="login"]/table/tbody/tr[3]/td[2]/input 
fail_element = //*[@id="_ctl0__ctl0_Content_Main_message"] 
sucess_element = //*[@id="btnGetAccount"]

URL : The target url to attempt password spray

Type : defines the type of attack, here it is headless which denotes usage of selenium to simulate browser. here the container has chromedriver so chrome or chromium browser is simulated. 

userList & passList : Text files with line by line of users and passwords that needs to be attempted. These are global lists which can be overridden for individual targets subsequently in the config file

Before moving to the next items, we need to talk about how to precisely identify elements inside a web page. For this selenium can make use of xpath notations. XPath (which stands for XML Path Language) is an expression language used to specify parts of an XML document. It is a syntax or language for finding any element on the web page using the XML path expression. XPath is used to find the location of any element on a webpage using HTML DOM structure. Below is a short video in getting the xpath notation of any specific element in a web page.

Now that we know how to easily get xpath notation of any elements in a page, lets look into the other items in form based config

username_field : This is where user name needs to be entered in the page

password_field : This is where password needs to be entered.

loginbtn_element : The webpage element that needs to be clicked so the login is initiated. typically this is a button. 

fail_element : This could be an error message or any other element in the page that denotes a failed login attempt. The selenium driver will look for this once the login click is initiated, if its present then it identifies that username password combo as failed attempt.

sucess_element : This is an element in the resulting page that determines a successful login, once selenium identifies this the username/password combo is marked as successful in the report. The tool will then continue further attempts in the list.


The solution generates a csv file spray_out.csv in the current working directory. The report contains status of each user name password combo attempted on each target defined in the configuration file. Also the attacking machines ip address is also logged so it could help with the purple teaming or similar activity at later stage.

Final thoughts

So thats basically it, I hope to extend the tool in future to accomodate more use cases and provide more features. If you would like to develop or contribute the solution please feel free to approach via github. If you like my work please support me by subscribing to youtube channel, facebook page or even reach out via telegram group.