Login Bruteforcing: Dictionary Attacks with Scripting Languages
Today, I'm continuing with the Login Bruteforcing Module. I recommend reading the previous post where I code a socket in C!
Dictionary Attacks
Passwords are a beautiful thing because people tend to use something they'll remember—something personal or very simple. Some choose their pet’s name, or their child’s name plus a birthday. Others take an easier route, using "password" for their password, or common choices like "qwerty" (the order of keys on most keyboards), "1234", or "password1234." The beauty lies in its simplicity. If a password is easy to remember, it can also be easy to guess. Dictionary Attacks rely on this beauty: you get a wordlist of common passwords or one tailored to the target, and try each one to log in on their behalf.
To learn more about this, the module does a better job at explaining Dictionary Attacks.
Hack the box provides python code to automate a dictionary attack, where get a list and send get requests to break in. As much fun as it was to code a socket in C, I shall not be using it today but rather I'll attempt a slightly different approach and make my own scripts in both powershell and bash.
HTB uses SecLists 500-worst-passwords.txt, so I'll go ahead and curl -O https://raw.githubusercontent.com/danielmiessler/SecLists/refs/heads/master/Passwords/500-worst-passwords.txt, and then write the script I'll use in bash
I am using the flag
-Oin curl which specifies that I'd like the file name to be the same as the one I am pulling from the internet.
Bash
#!/bin/bash
if [ "$#" -ne 2 ]; then
echo "Usage: <ip> <port>"
exit 1
fi
IP=$1
PORT=$2
WORDLIST='500-worst-passwords.txt'
if [ ! -f "$WORDLIST" ]; then
curl -s -O https://raw.githubusercontent.com/danielmiessler/SecLists/refs/heads/master/Passwords/500-worst-passwords.txt
fi
while read -r; do
echo "Sending: $REPLY"
response=$(curl -s -X POST "http://$IP:$PORT/dictionary" -d "password=$REPLY")
if grep "HTB" <<< "$response"; then
echo "Successful password: $REPLY"
echo "$response"
exit 0
fi
done < "$WORDLIST"For both scripts, I shall run them as ./executable <ip> <port>. So the first if statement checks that I am indeed passing two arguments.
Heads up here, be careful with the spaces, they are important in bash!
I continue by defining IP, PORT, and the WORDLIST.
Then we have a second if statement with the condition [ ! -f "$WORDLIST" ];. This condition can be translated to if WORDLIST is not a valid file and if it is true (WORDLIST is not a valid file), it curl it.
A fun modification to the script would be to add a third paramenter and pass a link to curl and extract data from there!
Then we read a line with read -r;. I could've added read -r password; but instead, I am using the default storage variable: $REPLY. The -r flag turns \n a new line into a string with the \n as characters, the flag turns the \ special character into a character.
Then we send the curl command, to get back a response from the server and we do a fun grep "HTB" <<< $response, sending the $response to the grep command, which looks for the string "HTB" in the $response. If found, it exits and returns the password
Powershell
The Powershell script looks way more intimidating than the bash script. I'll explain all the things I needed explanation with:
params()define the parameters. These are named parameters, which means we can also use$args[]and receive the parametersWrite-hostis the equivalent ofprint, it writes to the console.Test-Pathchecks that every element in the path exists. So if I have aC:\User\Downloads\text.txt, it will checkC:, thenUser, thenDownloads, and finallytext.txt. If any of these were missing, it would return false.Get-Contentreads the content inside the file, and combines it with a|ForEach-Object, it acts as a while loop.$_holds the current value in the pipeline. I could've assigned this to a readable variable and used the variable as$password = $_Invoke-RestMethodcan send HTTP requests.-Uriflag defines the target URL for the request. Then-Method,-Body, and-ContentTypeare part of the HTTP methods-ErrorActioncontrols how error is handled, although it did not matter much in my attempts to change it fromStop, toContinue, and finally toSilentlyContinue. The only thing that changed any outcome was thetry{..} catch {..}. Without thetry{..} catch {..}The script returns an error for every wrong password. I am going to explore this further in the future.And now, exit codes. You'll see
exit 1andexit 0. The1is an uncaught throw while the 0 is normal termination.
Both scripts successfully find the password and return the flag for this lab.
Thank you for reading! This may have been very technical, but this post was meant to explore some scripts to automate directory attacks directly in the terminal. The following posts will go through Hydra and Medusa for Login Bruteforcing. If you have any comments or would like to connect, I am always eager to chat on my LinkedIn
Last updated